题意:给出n个点和m条边,接着是m条边,代表从牛a到牛b需要花费c时间,现在所有牛要到牛x那里去参加聚会,并且所有牛参加聚会后还要回来,给你牛x,除了牛x之外的牛,他们都有一个参加聚会并且回来的最短时间,从这些最短时间里找出一个最大值输出。
思路:求出牛到x的最短路,求出牛从x到原地的最短路。
/*
这道题算是dijkstra的变形,求了两次对短路分别是:
1.i ——> x
2.x ——> i
最短路的思想在其中,所以很好的理解了松弛的条件
*/
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
int gragh[1110][1110];
int visit[1110],dis1[1110],dis2[1110];
int n,m,x;
int dijkstra()
{
memset(visit,0,sizeof(visit));
for(int i = 1;i <= n; i++){
dis1[i] = gragh[i][x];
dis2[i] = gragh[x][i];
}
visit[x] = true;
int pos;
for(int i = 1;i <= n; i++){
int Min = inf;
for(int j = 1;j <= n; j++){
if(visit[j] == 0 && Min > dis1[j]){
Min = dis1[j];
pos = j;
}
}
visit[pos] = true;
for(int j = 1;j <= n; j++){
if(dis1[j] > gragh[j][pos] + dis1[pos] && visit[j] == 0){ //j到x
dis1[j] = gragh[j][pos] + dis1[pos];
}
}
}
memset(visit,0,sizeof(visit));
visit[x] = true;
for(int i = 1;i <= n; i++){
int Min = inf;
for(int j = 1;j <= n; j++){
if(visit[j] == 0 && dis2[j] < Min){
Min = dis2[j];
pos = j;
}
}
visit[pos] = true;
for(int j = 1;j <= n; j++){
if(visit[j] == 0 && dis2[j] > dis2[pos] + gragh[pos][j]) //x到j
dis2[j] = dis2[pos] + gragh[pos][j];
}
}
int ans = 0;
for(int i = 1;i <= n; i++)
if(ans < dis1[i] + dis2[i] && i != x) //除了x
ans = dis1[i] + dis2[i];
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&x) != EOF) {
memset(gragh,inf,sizeof(gragh));
int d1,d2,q;
for(int i = 1;i <= m; i++){
scanf("%d%d%d",&d1,&d2,&q);
gragh[d1][d2] = q;
}
int ans = dijkstra();
printf("%d\n",ans);
}
return 0;
}