2014-11-05 86 views
-2

我想解決這個問題,我想我已經拿出了一個正確的答案,但我一直在得到法官的WA(錯誤答案)回覆。爲什麼我不斷爲WA獲得SPOJ FISHER的解決方案?

http://www.spoj.com/problems/FISHER/

問題蒸餾,給定一個完整的圖表,時間以及與每個邊緣相關聯收費,找到從第一節點到最後一個節點時間約束內的路徑和最小化的代價。

與任何問題一樣,有很多方法可以解決它。我的想法是擴展Floyd-Warshall算法以跟蹤所有非主導路徑。在算法結束時,我們以最小的成本提取路徑,並且如果有多條路徑具有相同的成本,請選擇花費最少的路徑。

除了複雜性外,壞事就是錯誤的答案。我不知道什麼是錯的。我已經生成了一些隨機圖並使用了一個蠻力解算器(一個可以嘗試所有可能路徑的解算器),它們恰好在小(即少於11個節點)圖上匹配。事不宜遲,這裏是代碼:

#include "stdafx.h" 

// http://www.spoj.com/problems/FISHER/ 

// #define LOG 

#include <iostream> 
#include <vector> 
#include <map> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    while (true) 
    { 
     int num_cities; 
     int time_budget; 
     vector<vector<int> > distances; 
     vector<vector<int> > tolls; 

     cin >> num_cities; 
     cin >> time_budget; 
     if (num_cities == 0 && time_budget == 0) 
     { 
      break; 
     } 
     distances.resize(num_cities); 
     tolls.resize(num_cities); 
     for (int i = 0; i < num_cities; i++) 
     { 
      distances[i].resize(num_cities); 
      tolls[i].resize(num_cities); 
     } 
     for (int i = 0; i < num_cities; i++) 
     { 
      for (int j = 0; j < num_cities; j++) 
      { 
       int distance; 
       cin >> distance; 
       distances[i][j] = distance; 
      } 
     } 
     for (int i = 0; i < num_cities; i++) 
     { 
      for (int j = 0; j < num_cities; j++) 
      { 
       int toll; 
       cin >> toll; 
       tolls[i][j] = toll; 
      } 
     } 

     // Try Floyd Warshall 
     // Denote the set of shortest paths from i to j going through {0,1,...k - 1} be shortest_paths[i][j][k], 
     // It is a set of shortest paths because there can be multiple shortest paths with different time used. 
     // We should record if using longer time can lead to lower cost, or similarly higher cost but less time 
     // The first element in the pair is the cost, the second element in the pair is time used 
     vector<vector<vector<vector<pair<int, int> > > > > shortest_paths; 
     shortest_paths.resize(num_cities); 
     for (int i = 0; i < num_cities; i++) 
     { 
      shortest_paths[i].resize(num_cities); 
      for (int j = 0; j < num_cities; j++) 
      { 
       shortest_paths[i][j].resize(num_cities + 1); 
      } 
     } 

     // Initialization - there is only one path without going through any node 
#ifdef LOG 
     cout << "k = " << 0 << endl; 
     cout << "<table border='1'>" << endl; 
#endif 
     for (int i = 0; i < num_cities; i++) 
     { 
#ifdef LOG 
      cout << "<tr>" << endl; 
#endif 

      for (int j = 0; j < num_cities; j++) 
      { 
#ifdef LOG 
       cout << "<td>(" << tolls[i][j] << ", " << distances[i][j] << ")</td>"; 
#endif 
       shortest_paths[i][j][0].push_back(pair<int, int>(tolls[i][j], distances[i][j])); 
      } 
#ifdef LOG 
      cout << "</tr>" << endl; 
#endif 
     } 
#ifdef LOG 
     cout << "</table>" << endl; 
#endif 
     // Iteration - the shortest path 
     for (int k = 1; k <= num_cities; k++) 
     { 
#ifdef LOG 
      cout << "k = " << k << endl; 
      cout << "<table border='1'>" << endl; 
#endif 
      for (int i = 0; i < num_cities; i++) 
      { 
#ifdef LOG 
       cout << "<tr>"; 
#endif 
       for (int j = 0; j < num_cities; j++) 
       { 
        // Step 1: Generate all candidate shortest paths 
        map<pair<int, int>, bool> candidates; 
        for (vector<pair<int, int> >::iterator pi = shortest_paths[i][j][k - 1].begin(); pi != shortest_paths[i][j][k - 1].end(); pi++) 
        { 
         candidates.insert(pair<pair<int, int>, bool>(*pi, false)); 
        } 
        for (vector<pair<int, int> >::iterator fi = shortest_paths[i][k - 1][k - 1].begin(); fi != shortest_paths[i][k - 1][k - 1].end(); fi++) 
        { 
         for (vector<pair<int, int> >::iterator si = shortest_paths[k - 1][j][k - 1].begin(); si != shortest_paths[k - 1][j][k - 1].end(); si++) 
         { 
          int first_path_cost = fi->first; 
          int first_path_time_used = fi->second; 
          int second_path_cost = si->first; 
          int second_path_time_used = si->second; 

          int new_path_cost = first_path_cost + second_path_cost; 
          int new_path_time_used = first_path_time_used + second_path_time_used; 

          if (new_path_time_used <= time_budget) 
          { 
           candidates.insert(pair<pair<int, int>, bool>(pair<int, int>(new_path_cost, new_path_time_used), false)); 
          } 
         } 
        } 

        vector<pair<pair<int, int>, bool> > candidates_list; 
        for (map<pair<int,int>, bool>::iterator ci = candidates.begin(); ci != candidates.end(); ci++) 
        { 
         candidates_list.push_back(*ci); 
        } 

        // Eliminate the bad ones 
        for (unsigned int p = 0; p < candidates_list.size(); p++) 
        { 
         for (unsigned int q = 0; q < candidates_list.size(); q++) 
         { 
          if (p != q) 
          { 
           int first_path_cost = candidates_list[p].first.first; 
           int first_path_time_used = candidates_list[p].first.second; 
           int second_path_cost = candidates_list[q].first.first; 
           int second_path_time_used = candidates_list[q].first.second; 

           // First take less time and less cost than second, second is eliminated 
           if (first_path_time_used <= second_path_time_used && first_path_cost <= second_path_cost) 
           { 
            candidates_list[q].second = true; 
           } 
          } 
         } 
        } 
#ifdef LOG 
        cout << "<td>"; 
#endif 
        for (unsigned int p = 0; p < candidates_list.size(); p++) 
        { 
         if (candidates_list[p].second == false) 
         { 
#ifdef LOG 
          cout << "(" << candidates_list[p].first.first << ", " << candidates_list[p].first.second << ")<br>"; 
#endif 
          shortest_paths[i][j][k].push_back(candidates_list[p].first); 
         } 
        } 
#ifdef LOG 
        cout << "</td>"; 
#endif 

       } 
#ifdef LOG 
       cout << "</tr>" << endl;; 
#endif 
      } 
#ifdef LOG 
      cout << "</table>" << endl; 
#endif 
     } 

     bool first = true; 
     int best_cost = -1; 
     int best_cost_time = -1; 
     for (vector<pair<int, int> >::iterator pi = shortest_paths[0][num_cities - 1][num_cities].begin(); pi != shortest_paths[0][num_cities - 1][num_cities].end(); pi++) 
     { 
      if (first) 
      { 
       best_cost = pi->first; 
       best_cost_time = pi->second; 
       first = false; 
      } 
      else 
      { 
       if (pi->first < best_cost) 
       { 
        best_cost = pi->first; 
        best_cost_time = pi->second; 
       } 
       if (pi->first == best_cost && pi->second < best_cost_time) 
       { 
        best_cost_time = pi->second; 
       } 
      } 
     } 
     cout << best_cost << " " << best_cost_time << endl; 
    } 

    return 0; 

} 
/* 
4 7 
0 5 2 3 
5 0 2 3 
3 1 0 2 
3 3 2 0 

0 2 2 7 
2 0 1 2 
2 2 0 5 
7 2 5 0 

0 0 

*/ 

打開的LOG,你將能夠看到弗洛伊德沃肖爾表中的每個迭代,每個小區已形成集(成本,時間)對。它們應該是所有非主導路徑的成本/時間對。

我真的很感激,如果有人能告訴我什麼是錯的。提前感謝!

+0

你或許應該張貼在這裏http://codereview.stackexchange.com/ – saruftw 2014-11-05 14:28:42

+0

CR通常是評論*工作*代碼。 – DSM 2014-11-05 14:34:36

+0

也許時間限制很嚴格,'new_path_rime_used ryanpattison 2014-11-05 15:30:39

回答

1

你可以做個試驗:

4 10 

0 1 1 1000 
1 0 1 1 
1 1 0 1 
1000 1 1 0 

0 1 1 1 
1 0 1 1 
1 1 0 1 
1 1 1 0 

基本上你需要確保distances[i][j] <= time_budget

shortest_paths[i][j][0].push_back(pair<int, int>(tolls[i][j], distances[i][j])); 
+0

解決這個簡單的錯誤後接受的代碼 - 感謝您的幫助! – 2014-11-06 03:56:46

+0

我想投票了這個答案 - 但我沒有所需的聲譽:( – 2014-11-06 05:29:41

+0

@AndrewAu:你可以也應該至少在問你問題時接受答案,這裏是關於你如何以及爲什麼接受回答:http://meta.stackexchange.com/a/5235/271768 – 2015-12-22 00:01:13

相關問題