AHU-744 你来擒孟获 【Dijkstra】
Description
三国时期,南蛮王孟获叛乱,诸葛亮起兵平乱。
当深入南蛮之地时,遇当地人绘得地图,发现各地分别由各个寨主据守,若诸葛亮想兵分多路进军,尽快占领各个山寨(必须占领所有山寨),并且最终所有士兵都汇聚到孟获所在山寨,若给你一次穿越的机会,你用程序告诉诸葛亮最少需要多少天才能完成这个任务。假设军队足够多,各分队行军速度一样,且诸葛亮神机妙算,到达每个山寨即日可以攻克。
Input
首先是一个正整数T,接下来是T组测试数据,每组数据第一行是两个整数n,m 2<=n<=1000,1<=m<=10000 ,分别表示山寨数量和总边数,山寨编号0,1,2,3….n-1接下来m行,每行三个整数i,j,k 0<=i,j < n,k<=10^4 ,分别表示山寨i和山寨j之间有一条路,在这条路上需要行军k天,接下来一行两个整数s,t 0<=s,t<=n-1,分别表示诸葛亮所在部队的起点和孟获山寨所在终点的编号
Output
对每组数据输出一个整数,表示诸葛亮的士兵占领所有山寨并汇聚到孟获所在山寨所需要的最少天数,每个输出独占一行
Sample Input
2 5 6 0 1 2 1 2 2 3 1 2 4 0 3 3 2 3 3 4 1 4 3 5 5 1 0 1 1 2 3 1 3 3 4 2 2 3 4 1 4 2
Sample Output
7 9
思路:
简单的Dijkstra,先算出源点到各点的最短路,再算出终点(除源点和终点)到各点的最短路,两次Dijkstra,取和的最大值。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<vector> 7 #include<set> 8 #include<map> 9 #include<string> 10 11 using namespace std; 12 #define INF 0x3f3f3f3f 13 const int maxn = 2000 + 5; 14 int temp[maxn]; 15 16 struct Edge { 17 int from, to, dist; 18 }; 19 20 struct Node { 21 int d, u; 22 bool operator < (const Node& rhs) const { 23 return d > rhs.d; 24 } 25 }; 26 27 struct Dijkstra { 28 int n, m; 29 vector<Edge> edges; 30 vector<int> G[maxn]; 31 int d[maxn]; 32 bool done[maxn]; 33 34 void init(int n) { 35 this->n = n; 36 for (int i = 0; i <= n; ++i) 37 G[i].clear(); 38 edges.clear(); 39 } 40 41 void AddEdge(int from, int to, int dist) { 42 edges.push_back((Edge){from, to, dist}); 43 m = edges.size(); 44 G[from].push_back(m-1); 45 } 46 47 void dijkstra(int s) { 48 priority_queue<Node> Q; 49 memset(done, 0, sizeof(done)); 50 memset(d, INF, sizeof(d)); 51 d[s] = 0; 52 Q.push((Node){d[s], s}); 53 while(!Q.empty()) { 54 Node x = Q.top(); Q.pop(); 55 int u = x.u; 56 if (done[u]) continue; 57 done[u] = true; 58 int len = G[u].size(); 59 for (int i = 0; i < len; ++i) { 60 Edge &e = edges[G[u][i]]; 61 if (d[e.to] > d[u] + e.dist) { 62 d[e.to] = d[u] + e.dist; 63 Q.push((Node){d[e.to], e.to}); 64 } 65 } 66 } 67 } 68 69 }; 70 71 Dijkstra di; 72 73 int main() { 74 int n, m, a, b, c, T; 75 cin>>T; 76 while(T--) { 77 cin>>n>>m; 78 di.init(n); 79 while(m--) { 80 cin>>a>>b>>c; 81 di.AddEdge(a, b, c); 82 di.AddEdge(b, a, c); 83 } 84 int s, e, ans = 0; 85 cin>>s>>e; 86 di.dijkstra(s); 87 ans = max(di.d[e], ans); 88 for (int i = 0; i < n; ++i) 89 if (i != s && i != e) temp[i] = di.d[i]; 90 di.dijkstra(e); 91 for (int i = 0; i < n; ++i) 92 if (i != s && i != e) { 93 ans = max(ans, temp[i] + di.d[i]); 94 } 95 cout<<ans<<endl; 96 } 97 98 return 0; 99 }