思路:有向图。假设在X牧场参加party,从X回家的时候,以X为起点,使用一次Dijkstra算法即可。难点在于去X参加party的最短路如何求解。
这时候我们可以反向建图,即把原来有向图的方向全部反向,形成一幅新的有向图G',此时再对G'使用一次以X为起点的Dijkstra算法即
可求得原图G中其他各点以X为终点的最短路径。
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<cmath> 5 #include<set> 6 #include<algorithm> 7 #include<cstdio> 8 #include<map> 9 #include<cstring> 10 11 #define INF 1000000000 12 13 using namespace std; 14 15 int dis1[1010]; // 正向最短路 (回家的最短路) 16 int dis2[1010]; // 反向最短路 (去party的最短路) 17 int vis[1010]; 18 int g1[1010][1010]; // 正向建图 19 int g2[1010][1010]; // 反向建图 20 int N, M, X; 21 22 void dijkstra(int start, int dis[], int g[1010][1010]) 23 { 24 for(int i = 1; i <= N; ++i) 25 { 26 dis[i] = INF; 27 vis[i] = 0; 28 } 29 30 dis[start] = 0; 31 while(1) 32 { 33 int mark = -1, minDis = INF; 34 for(int i = 1; i <= N; ++i) 35 { 36 if(!vis[i] && dis[i] < minDis) 37 { 38 minDis = dis[i]; 39 mark = i; 40 } 41 } 42 if(mark == -1) 43 break; 44 vis[mark] = 1; 45 for(int i = 1; i <= N; ++i) 46 { 47 if(!vis[i]) 48 dis[i] = min(dis[i], dis[mark]+g[mark][i]); 49 } 50 51 } 52 53 54 55 } 56 57 int main() 58 { 59 scanf("%d %d %d", &N, &M, &X); 60 for(int i = 1; i <= N; ++i) 61 { 62 for(int j = 1; j <= N; ++j) 63 { 64 if(i == j) 65 g1[i][j] = g2[i][j] = 0; 66 else 67 g1[i][j] = g2[i][j] = INF; 68 } 69 } 70 for(int i = 1; i <= M; ++i) 71 { 72 int a, b, cost; 73 scanf("%d %d %d", &a, &b, &cost); 74 g1[a][b] = cost; 75 g2[b][a] = cost; 76 } 77 78 dijkstra(X, dis1, g1); 79 dijkstra(X, dis2, g2); 80 81 82 int ans = -1; 83 84 for(int i = 1; i <= N; ++i) 85 { 86 if(dis1[i] + dis2[i] > ans) 87 ans = dis1[i] + dis2[i]; 88 } 89 90 printf("%d ", ans); 91 92 return 0; 93 }