http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1456
题意:
求最短路并且输出字典序最小的答案。
思路:
如果用dijkstra来做的话,会比较麻烦,这里直接用floyd会简单的多,只需要记录好后继路径即可。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 1000 + 5; 17 18 int n, m; 19 20 int val[maxn]; 21 int mp[maxn][maxn]; 22 int path[maxn][maxn]; 23 24 void floyd() 25 { 26 for(int k=1;k<=n;k++) 27 { 28 for(int i=1;i<=n;i++) 29 { 30 for(int j=1;j<=n;j++) 31 { 32 if(mp[i][k]==INF || mp[k][j]==INF) continue; 33 int sum=mp[i][k]+mp[k][j]+val[k]; 34 if(mp[i][j]>sum) 35 { 36 mp[i][j]=sum; 37 path[i][j]=path[i][k]; 38 } 39 else if(mp[i][j]==sum && path[i][j]>path[i][k]) 40 path[i][j]=path[i][k]; 41 } 42 } 43 } 44 } 45 46 int main() 47 { 48 //freopen("in.txt","r",stdin); 49 while(~scanf("%d",&n) && n) 50 { 51 for(int i=1;i<=n;i++) 52 for(int j=1;j<=n;j++) 53 { 54 scanf("%d",&mp[i][j]); 55 if(mp[i][j]==-1) mp[i][j]=INF; 56 path[i][j]=j; //i的后继路径为j 57 } 58 for(int i=1;i<=n;i++) scanf("%d",&val[i]); 59 floyd(); 60 61 while(true) 62 { 63 int s,t; 64 scanf("%d%d",&s,&t); 65 if(s==-1 && t==-1) break; 66 printf("From %d to %d : ",s,t); 67 printf("Path: %d",s); 68 int tmp=s; 69 while(tmp!=t) 70 { 71 printf("-->%d",path[tmp][t]); 72 tmp=path[tmp][t]; 73 } 74 printf(" "); 75 printf("Total cost : %d ",mp[s][t]); 76 } 77 } 78 return 0; 79 }