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#include<stdio.h> #include<queue> using namespace std; const int N =105; const int inf = 999999999; struct PATH { int k,path[N],dis; }; int n,mapt[N][N],dis[N],frome[N],b[N]; PATH p[N][N]; bool compare(int x,int y) { int k[2]={0},a[2][N]; while(frome[x]!=x) { a[0][k[0]++]=x; x=frome[x]; } a[1][k[1]++]=x; while(frome[y]!=y) { a[1][k[1]++]=y; y=frome[y]; } while(k[1]&&k[0]) { k[0]--; k[1]--; if(a[0][k[0]]>a[1][k[1]]) return true; else if(a[0][k[0]]<a[1][k[1]]) return false; } if(k[0]) return true; return false; } void spfa() { queue<int>q; int inq[N]={0},s; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) dis[j]=inf,frome[j]=j; dis[i]=0; q.push(i); while(!q.empty()) { s=q.front(); q.pop(); inq[s]=0; for(int j=1;j<=n;j++) if(mapt[s][j]!=-1&&j!=s) { if(dis[j]>dis[s]+mapt[s][j]+b[j]) { dis[j]=dis[s]+mapt[s][j]+b[j]; frome[j]=s; if(!inq[j]) inq[j]=1,q.push(j); } else if(dis[j]==dis[s]+mapt[s][j]+b[j]) { if(compare(j,s)) frome[j]=s; } } } for(int j=1;j<=n;j++) { p[i][j].k=0; p[i][j].dis=dis[j]; if(j!=i) p[i][j].dis-=b[j]; int &k=p[i][j].k; if(i!=j) //起点与终点相同时,只输出一个点 p[i][j].path[k++]=j; s=frome[j]; while(s!=frome[s]) { p[i][j].path[k++]=s; s=frome[s]; } p[i][j].path[k++]=i; } } } int main() { int a,aa; while(scanf("%d",&n)>0&&n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&mapt[i][j]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); spfa(); while(scanf("%d%d",&a,&aa)>0&&a+aa>0) { printf("From %d to %d :\n",a,aa); printf("Path: %d",a); int k=p[a][aa].k-1; while(k>0) { k--; printf("-->%d",p[a][aa].path[k]); } printf("\nTotal cost : %d\n\n",p[a][aa].dis); } } }
HDU1385Minimum Transport Cost(两点间最短spfa+输出字典树最小的路径)
原文地址:http://blog.csdn.net/u010372095/article/details/44889521