PC/UVa:110903/10099
用这道题回顾了一下Dijkstra算法,自己写一遍就知道Dijkstra是贪心算法了(这个贪心也很好想,至少我觉得是),而Floyd是动态规划。
当年大二上数据结构的时候好几个小时才把这玩意吭哧出来,现在半小时搞定了,人丑就要多读书啊!
这版本写的跟上周搞的A*算法比较类似,有点像带估价函数的广搜。viClose保存不需要再次扩展的节点了,也就是已经找到了单源最优值,viOpen是待扩展节点,如果当前节点到一个待扩展节点有更优值,那么就更新它(如果要记录路径的话,也就是父节点,那么就应该是在更新viOpen的时候更新path)。
#include <iostream>
#include <vector>
using namespace std;
int Min(int i1, int i2)
{
return i1 < i2 ? i1 : i2;
}
void findMaxPath(const vector<vector<int>> &Graph, const int S, const int D, const int T)
{
vector<int> viClose(Graph.size(), -1);
vector<int> viOpen(Graph.size(), -1);
size_t curr = S, maxIdx;
int maxTourist;
viOpen[curr] = T + 1;
while (1){
//在待扩展节点中找最优值
maxIdx = 0;
maxTourist = viOpen[0];
for (size_t idx = 1; idx < viOpen.size(); idx++)
{
if (viOpen[idx] > viOpen[maxIdx]){
maxIdx = idx;
maxTourist = viOpen[idx];
}
}
if (maxTourist == -1) break;
curr = maxIdx;
viClose[curr] = viOpen[curr];
viOpen[curr] = -1;//此节点已经找到单源最优值,为了不影响后续找最大值,将其恢复原始状态
if (curr == D) break;
for (size_t adj = 0; adj < Graph.size(); adj++)
{
if (Graph[curr][adj] != -1 && viClose[adj] == -1){//当前邻接点还未找到最优值
maxTourist = Min(viClose[curr], Graph[curr][adj]);
if (maxTourist > viOpen[adj]){
viOpen[adj] = maxTourist;
}
}
}
}
maxTourist = viClose[D];
int iTrips = T / (maxTourist - 1);
if (T % (maxTourist - 1) != 0) iTrips++;
cout << "Minimum Number of Trips = " << iTrips << endl << endl;
}
int main()
{
int scenario = 1;
int N, R;
while (cin >> N >> R){
if (N == 0 && R == 0) break;
vector<vector<int>> Graph(N, vector<int>(N, -1));
int C1, C2, P, S, D, T;
for (int r = 0; r < R; r++)
{
cin >> C1 >> C2 >> P;
Graph[C1 - 1][C2 - 1] = Graph[C2 - 1][C1 - 1] = P;
}
cin >> S >> D >> T;
cout << "Scenario #" << scenario++ << endl;
findMaxPath(Graph, S - 1, D - 1, T);
}
return 0;
}
/*
7 10
1 2 30
1 3 15
1 4 10
2 4 25
2 5 60
3 4 40
3 6 20
4 7 35
5 7 20
6 7 30
1 7 99
0 0
*/
本文通过解决一道题目,回顾并实践了Dijkstra算法,同时与Floyd算法进行了对比,介绍了两种算法的不同特点及应用。Dijkstra算法被描述为一种贪心算法,适合寻找单源最短路径;而Floyd算法则被视为动态规划算法,适用于解决所有顶点间的最短路径问题。

被折叠的 条评论
为什么被折叠?



