最短路模板(二)——用拓撲排序解決有向無環圖中的最短路
阿新 • • 發佈:2019-02-02
測試資料:
8 13
5 4 0.35
4 7 0.37
5 7 0.28
5 1 0.32
4 0 0.38
0 2 0.26
3 7 0.39
1 3 0.29
7 2 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93
測試結果:
5 to 0 : 0.73
5 to 1 : 0.32
5 to 2 : 0.62
5 to 3 : 0.61
5 to 4 : 0.35
5 to 5 : 0.00
5 to 6 : 1.13
5 to 7 : 0.28
說明:該演算法亦適用於含有負權重邊的圖。
程式碼:
#include<cstdio> #include<cstring> #include<vector> #include<queue> #include<utility> #include<functional> using namespace std; const int mx = 10005; struct edge { double cost; int to; void read() { scanf("%d%lf", &to, &cost); } } e; vector<edge> G[mx]; double disTo[mx]; bool vis[mx]; int topo[mx], cnt; void dfs(int i) { vis[i] = true; for (int j = 0; j < G[i].size(); ++j) if (!vis[G[i][j].to]) dfs(G[i][j].to); topo[cnt++] = i; } /// 有向無環圖上的最短路 void dagSP(int s) { int i = cnt, j, v; while (topo[--i] != s); /// 先在topo中找到s memset(disTo, 100, sizeof(disTo)); disTo[s] = 0.0; for (; i >= 0; --i) { v = topo[i]; for (j = 0; j < G[v].size(); ++j) { e = G[v][j]; /// v視作e.from disTo[e.to] = min(disTo[e.to], disTo[v] + e.cost); } } } int main() { int n, m, i, a; while (~scanf("%d%d", &n, &m)) { for (i = 0; i < n; ++i) G[i].clear(); while (m--) { scanf("%d", &a); e.read(); G[a].push_back(e); } memset(vis, 0, sizeof(vis)); cnt = 0; for (i = 0; i < n; ++i) if (!vis[i]) dfs(i); dagSP(5); for (i = 0; i < n; ++i) printf("5 to %d : %.2f\n", i, disTo[i]); putchar(10); } return 0; }