HDU_1385
这个题目又使我获益不少。
由于后续的查询工作都是对同一个图而言的,因此用Floyd算法扫一遍图就可以了。为了辅助打印路径,我们引入一个数组path[i][j]表示由i到j首先要经过的城市。一开始把所有的path[i][j]都初始化成j并没有什么不妥,尽管其中有些path[i][j]的值是错误的,但凡是错误的值,在之后运算的过程中都不用到,因为如果path[i][j]是错误的,那么必然f[i][j]是INF。
#include<stdio.h>
#include<string.h>
int f[1010][1010],path[1010][1010],b[1010],N;
int init()
{
int i,j,k;
scanf("%d",&N);
if(N==0)
return 0;
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
{
scanf("%d",&f[i][j]);
if(f[i][j]==-1)
f[i][j]=1000000000;
}
for(i=1;i<=N;i++)
scanf("%d",&b[i]);
return 1;
}
void floyd()
{
int i,j,k,temp;
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++)
{
temp=f[i][k]+f[k][j]+b[k];
if(temp<f[i][j])
{
f[i][j]=temp;
if(i!=k)
path[i][j]=path[i][k];
}
else if(temp==f[i][j]&&path[i][k]<path[i][j])
path[i][j]=path[i][k];
}
}
printpath(int u,int v)
{
printf("%d",u);
while(u!=v)
{
u=path[u][v];
printf("-->%d",u);
}
}
int main()
{
int u,v;
while(init())
{
floyd();
while(1)
{
scanf("%d%d",&u,&v);
if(u==-1)
break;
printf("From %d to %d :\n",u,v);
printf("Path: ");
printpath(u,v);
printf("\n");
printf("Total cost : %d\n",f[u][v]);
printf("\n");
}
}
return 0;
}