5 0 3 22 -1 4 3 0 5 -1 -1 22 5 0 9 20 -1 -1 9 0 4 4 -1 20 4 0 5 17 8 3 1 1 3 3 5 2 4 -1 -1 0
From 1 to 3 : Path: 1-->5-->4-->3 Total cost : 21 From 3 to 5 : Path: 3-->4-->5 Total cost : 16 From 2 to 4 : Path: 2-->1-->5-->4 Total cost : 17
1、这里我们更新的map【i】【j】代表过路费,不要忘记val【k】的存在、
2、输出路径:我们初始化路径path【i】【j】=j、当path【i】【j】路径经过点k松弛之后,path【i】【j】=path【i】【k】。
3、字典序输出:当map【i】【j】==map【i】【k】+map【k】【j】+val【k】的时候,当path【i】【j】>path【i】【k】的时候,更新path【i】【j】为path【i】【k】、保证了过路费最小且相等的时候,使得字典序最小。
floyd部分代码:
void floyd() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int k=1;k<=n;k++) { if(a[j][k]>a[j][i]+a[i][k]+val[i])//更新最小权值 { a[j][k]=a[j][i]+a[i][k]+val[i]; path[j][k]=path[j][i];//更新路径 } else if(a[j][k]==a[j][i]+a[i][k]+val[i]&&path[j][k]>path[j][i]) { path[j][k]=path[j][i];//保证字典序 } } } } }
#include<stdio.h> #include<string.h> #include<vector> using namespace std; int a[1200][1200]; int val[1200]; int path[1200][1200]; int n; void floyd() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { for(int k=1;k<=n;k++) { if(a[j][k]>a[j][i]+a[i][k]+val[i]) { a[j][k]=a[j][i]+a[i][k]+val[i]; path[j][k]=path[j][i]; } else if(a[j][k]==a[j][i]+a[i][k]+val[i]&&path[j][k]>path[j][i]) { path[j][k]=path[j][i]; } } } } } int main() { while(~scanf("%d",&n)) { if(n==0)break; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { path[i][j]=j; scanf("%d",&a[i][j]); if(a[i][j]==-1)a[i][j]=0x3f3f3f3f; } } for(int i=1;i<=n;i++) { scanf("%d",&val[i]); } floyd(); int st,ed; /* for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { printf("%d ",path[i][j]); } printf("\n"); }*/ while(scanf("%d%d",&st,&ed)) { if(st==-1&&ed==-1)break; printf("From %d to %d :\n",st,ed); printf("Path: "); int u=st; printf("%d",u); while(u!=ed) { printf("-->%d",path[u][ed]); u=path[u][ed]; } printf("\nTotal cost : %d\n",a[st][ed]); printf("\n"); } } }