题意是有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 :\n",p,q);
i=p;
if(p==q) //p==q时单独讨论
printf("Path: %d\n",p);
else
{
printf("Path: ");
printf("%d-->",p);
while(path[i][q]!=q)
{
printf("%d-->",path[i][q]);
i=path[i][q];
}
printf("%d\n",q);
}
printf("Total cost : %d\n\n",dist[p][q]);
}
}
return 0;
}