#include<stdio.h>
#include<iostream>
#include<string.h>
#include <algorithm>
#define INF 100000005
using namespace std;
int g[105][105], wi[105];//wi点权
int path[105][105];//路径,记录当前i到j的最短路的第一个节点
int n;
void floyd(){
for(int k = 1; k <= n; k ++){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
if(g[i][j] > g[i][k] + g[k][j] + wi[k]){
g[i][j] = g[i][k] + g[k][j] + wi[k];
path[i][j] = path[i][k]; //记录路径path[i][k]的后继
}
else if(g[i][j] == g[i][k] + g[k][j] + wi[k] && path[i][j] > path[i][k]){//j>k;
path[i][j] = path[i][k]; //每次要选择字典序小的路径
}
}
}
}
}
int main(){
//freopen("11.txt", "r", stdin);
while(scanf("%d",&n) ){
if(n==0)break;
memset(path,-1,sizeof(path));
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){//对g[][]以及path[][]进行初始化
scanf("%d",&g[i][j]);
if(g[i][j] == -1)
g[i][j] = INF;
else
path[i][j] = j;
}
}
for(int i = 1; i <= n; i ++)
scanf("%d",&wi[i]);
floyd(); //调用floyd算法
int u,v;
while(~scanf("%d%d",&u,&v)){
if(u == -1 && v == -1)
break;
printf("From %d to %d :\n",u,v);
printf("Path: ");
printf("%d",u);
if(u == v){ //起点和终点是同一个点时,直接输出即可
printf("\n");
}
else{
int next = path[u][v]; //u,v之间的第一个中间结点 ,path[][]路径,i->k->j一定是 k->j也是最短路
while(next != v){
printf("-->%d",next);
next = path[next][v];
}
printf("-->%d\n",v);
}
printf("Total cost : %d\n\n",g[u][v]);
}
}
return 0;
}
11-20
239
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)