题意:如图,要求求出最短路径,且输出路径,与总花费,如果有多条最短路径,按字典序排序,输出较小的。
算法:Floyd
问题:没看到字典序;输出各组之间需要空行,先当然以为最后一组后面不用写;最主要的是floyd的写法,存储数据的时候应该把d[i][i]存储为0,其余为极大值或极小值(对应题意),之和三重循环时内部应该无需再判断什么额外条件了。path数组先全部初始化为0,再在存储m条路时存储相关信息,最后在三重循环内存储如果改变到k点的信息,输出路径则靠一个循环,循环里输出path[s][e];s=path[s][e]即可,直到s==e。
思路: 如上。
代码:ac
#include<bits/stdc++.h>
using namespace std;
#define inf 99999999
int d[1010][1010];
int path[1010][1010];
int n;
int a, b;
int fun[1010];
int main()
{
while (scanf("%d", &n), n) {
for(int i=1;i<=n;i++)
for (int j = 1; j <= n; j++) {
scanf("%d", &d[i][j]);
if (d[i][j] == -1)d[i][j] = inf;
path[i][j] = 0;
}
for (int i = 1; i <= n; i++)
scanf("%d", &fun[i]);
for(int i=1;i<=n;i++)
for (int j = 1; j <= n; j++) {
if (d[i][j] != inf ) {
d[i][j] += fun[j];
path[i][j] = j;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for (int j = 1; j <= n; j++) {
if (d[i][j] > d[i][k] + d[k][j]) {
d[i][j] = d[i][k] + d[k][j];
path[i][j] = path[i][k];
}
else if (d[i][j] == d[i][k] + d[k][j]) {
if (path[i][j] > path[i][k])
path[i][j] = path[i][k];
}
}
int s, e;
/*int flag = 0;*/
while (scanf("%d%d", &s, &e)) {
if (s == -1 && e == -1)break;
/*if (flag)printf("\n");
flag = 1;*/
int sum;
printf("From %d to %d :\n", s, e);
printf("Path: ");
sum = d[s][e] - fun[e];
while (s != e) {
printf("%d-->",s);
s = path[s][e];
}
printf("%d\n", e);
printf("Total cost : %d\n\n", sum);
}
}
return 0;
}