One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.
Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.
Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?
Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2.. M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Lines 2.. M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
Sample Input
4 8 2 1 2 4 1 3 2 1 4 7 2 1 1 2 3 5 3 1 2 3 4 4 4 2 3
Sample Output
10
Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
题意:第一行输入n,m,x。有n个点,每个点上都有一只牛,两个点之间有通道,通道是单向的,,往下m行输入的是两个点的编号和通过通道的时间,问每个牛都去x点聚会并回来,其中牛花费的最长时间是多少。注意,去的道路可能与回来的道路不同。
思路:最短路求法,但有一点不同,需要n点中除x点以外,其他点到x点又回家的时间和的最大值,可以以x为起点,从x到其他点为回家,从其他点到x为去,两个dijsktra算法即可,一个正向图,一个反向图。
代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //ma用来存放两个点之间的距离 22 int ma[1010][1010]; 23 //dis用来存放到1之间的距离 24 int dis1[1010]; 25 int dis2[1010]; 26 //vis数组标记已经找过的最大起重 27 bool vis[1010]; 28 29 //从x到其他地方的正向图 30 void dijkstra1(int m,int q) 31 { 32 memset(vis,0,sizeof(vis)); 33 memset(dis1,INF,sizeof(dis1)); 34 vis[q]=0; 35 //初始时间为0; 36 dis1[q]=0; 37 for(int i=1;i<=m;i++) 38 { 39 int mi=INF; 40 int k=-1; 41 //寻找x到其他地方的最小值 42 for(int j=1;j<=m;j++) 43 { 44 if(!vis[j]&&mi>dis1[j]) 45 { 46 mi=dis1[j]; 47 k=j; 48 } 49 } 50 //如果没有最小值,则退出循环 51 if(k==-1) 52 { 53 break; 54 } 55 vis[k]=1; 56 for(int j=1;j<=m;j++) 57 { 58 //从x到k的时间与从k到其他地方的时间之和与从x到其他地方的时间取最小值 59 dis1[j]=min(dis1[j],dis1[k]+ma[k][j]); 60 } 61 } 62 } 63 //从x到其他地方的反向图 64 void dijkstra2(int m,int q) 65 { 66 memset(vis,0,sizeof(vis)); 67 memset(dis2,INF,sizeof(dis2)); 68 vis[q]=0; 69 //初始时间为0; 70 dis2[q]=0; 71 for(int i=1;i<=m;i++) 72 { 73 int mi=INF; 74 int k=-1; 75 //寻找x到其他地方的最小值 76 for(int j=1;j<=m;j++) 77 { 78 if(!vis[j]&&mi>dis2[j]) 79 { 80 mi=dis2[j]; 81 k=j; 82 } 83 } 84 //如果没有最小值,则退出循环 85 if(k==-1) 86 { 87 break; 88 } 89 vis[k]=1; 90 for(int j=1;j<=m;j++) 91 { 92 //从x到k的时间与从其他地方到k的时间之和与从x到其他地方的时间取最小值 93 dis2[j]=min(dis2[j],dis2[k]+ma[j][k]); 94 } 95 } 96 } 97 98 int main() 99 { 100 int n,m,x; 101 scanf("%d %d %d",&n,&m,&x); 102 int a,b,c; 103 //因为要求的是最小时间,所以初始化为无穷 104 memset(ma,INF,sizeof(ma)); 105 for(int i=1;i<=m;i++) 106 { 107 scanf("%d %d %d",&a,&b,&c); 108 ma[a][b]=c; 109 } 110 //回来的 111 dijkstra1(n,x); 112 //去的 113 dijkstra2(n,x); 114 int ans=0; 115 for(int i=1;i<=n;i++) 116 { 117 //所有牛花费时间中最大的一个 118 ans=max(ans,dis1[i]+dis2[i]); 119 } 120 printf("%d ",ans); 121 }