我想解決這個問題,我想我已經拿出了一個正確的答案,但我一直在得到法官的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,你將能夠看到弗洛伊德沃肖爾表中的每個迭代,每個小區已形成集(成本,時間)對。它們應該是所有非主導路徑的成本/時間對。
我真的很感激,如果有人能告訴我什麼是錯的。提前感謝!
你或許應該張貼在這裏http://codereview.stackexchange.com/ – saruftw 2014-11-05 14:28:42
CR通常是評論*工作*代碼。 – DSM 2014-11-05 14:34:36
也許時間限制很嚴格,'new_path_rime_used
ryanpattison
2014-11-05 15:30:39