https://vjudge.net/problem/POJ-3268
题目大意:
n个农场的n头奶牛将前往x农场,要选择一条来回时间最短的路径。
(一头牛的返回路线可能不同于她最初去派对的路线,因为道路是单向的。)
思路:
//有向图的迪杰斯特拉
如果以每头牛为起点遍历其到x的最短路,耗时太大。
有没有简便的方法呢?
如果,以x为起点,找到其余点的最短路,这求出的便是牛返回各自农场的最短路,
由于还要求牛前往x农场的最短路,
我们可以想到一个巧妙的方法:将所有的方向反向,再求一遍以x为起点,找到其余点的最短路。
所以就是在最短路的代码上加一个反向最短路。
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<string.h> 5 #define maxn 1005 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 int cost[maxn][maxn],n,m,x; 9 int disback[maxn],discome[maxn]; 10 bool vis[maxn]; 11 int dij(int x) 12 { 13 int u,minn; 14 for(int i=1;i<=n;i++) 15 { 16 disback[i]=cost[x][i]; 17 discome[i]=cost[i][x];//将各边反转 18 } 19 for(int i=1;i<n;i++) 20 { 21 u=-1,minn=inf; 22 for(int j=1;j<=n;j++) 23 { 24 if(!vis[j]&&disback[j]<minn) 25 { 26 u=j; 27 minn=disback[j]; 28 } 29 } 30 //if(u=-1)return 31 vis[u]=1; 32 for(int v=1;v<=n;v++) 33 { 34 if(!vis[v]&&cost[u][v]!=inf) 35 { 36 if(disback[u]+cost[u][v]<disback[v]) 37 disback[v]=disback[u]+cost[u][v]; 38 } 39 } 40 } 41 memset(vis,0,sizeof vis); 42 for(int i=1;i<n;i++) 43 { 44 minn=inf,u=-1; 45 for(int j=1;j<=n;j++) 46 { 47 if(!vis[j]&&discome[j]<minn) 48 { 49 u=j; 50 minn=discome[j]; 51 } 52 } 53 vis[u]=1; 54 for(int j=1;j<=n;j++) 55 { 56 if(!vis[j]&&cost[j][u]+discome[u]<discome[j]) 57 discome[j]=cost[j][u]+discome[u]; 58 } 59 } 60 minn=-1; 61 for(int i=1;i<=n;i++) 62 minn=max(minn,discome[i]+disback[i]); 63 return minn; 64 } 65 int main() 66 { 67 int i,a,b,c,j; 68 while(~scanf("%d%d%d",&n,&m,&x)) 69 { 70 for(i=1;i<=n;i++) 71 for(j=1;j<=n;j++) 72 { 73 if(i!=j) 74 cost[i][j]=inf; 75 else 76 cost[i][j]=0; 77 } 78 for(i=0;i<m;i++) 79 { 80 scanf("%d%d%d",&a,&b,&c); 81 cost[a][b]=c; 82 } 83 printf("%d ",dij(x)); 84 } 85 return 0; 86 }