题意是有n个国家,求从某点到某点运输的最小费用,且中间经过的点需要收税,还按字典序要打印出路径。
floyd算法多加上枚举点的税即可。
path[ i ][ j ]记录从i到j的第一个节点,当有相等的情况时比较两种path即可按字典序输出。
#include <stdio.h> #define INF 10000000 int dist[1010][1010],n,path[1010][1010],b[1010]; void floyd() { int k,i,j,t; for(i=1;i<=n;i++) for(j=1;j<=n;j++) path[i][j]=j; //记录后驱节点 for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(k==i||k==j) continue; if(i==j) continue; t=dist[i][k]+dist[k][j]+b[k]; //经过中间节点k要交税 if(t<dist[i][j]) { dist[i][j]=t; path[i][j]=path[i][k]; } else if(t==dist[i][j]) { if(path[i][j]>path[i][k]) path[i][j]=path[i][k]; } } } int main() { int i,j,p,q,x; while(1) { scanf("%d",&n); if(n==0) break; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { dist[i][j]=INF; scanf("%d",&x); if(x==-1) continue; dist[i][j]=x; } for(i=1;i<=n;i++) scanf("%d",&b[i]); floyd(); while(1) { scanf("%d%d",&p,&q); if(p==-1&&q==-1) break; printf("From %d to %d : ",p,q); i=p; if(p==q) //p==q时单独讨论 printf("Path: %d ",p); else { printf("Path: "); printf("%d-->",p); while(path[i][q]!=q) { printf("%d-->",path[i][q]); i=path[i][q]; } printf("%d ",q); } printf("Total cost : %d ",dist[p][q]); } } return 0; }