Files
python/TangDou/Topic/HDU1385.cpp

70 lines
1.9 KiB
C++
Raw Normal View History

2025-08-30 18:35:01 +08:00
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
const int INF = 0x3f3f3f3f;
// Floyd+记录起点后继
int n;
int g[N][N], w[N];
int path[N][N]; // 记录i到j最短路径中i的后继
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] + w[k]) {
g[i][j] = g[i][k] + g[k][j] + w[k];
path[i][j] = path[i][k]; // i->j这条最短路径上,i后面第一个节点,是i->k路径上第一个节点
}
// 相同路径下选择后继更小的(为了字典序)
if (g[i][j] == g[i][k] + g[k][j] + w[k])
if (path[i][j] > path[i][k])
path[i][j] = path[i][k];
}
}
// 递归输出路径
void print(int s, int e) {
printf("-->%d", path[s][e]); // 输出s的后继
if (path[s][e] != e) // 如果不是直连
print(path[s][e], e); // 递归输出后继
}
/*
From 1 to 3 :
Path: 1-->5-->4-->3
Total cost : 21
From 3 to 5 :
Path: 3-->4-->5
Total cost : 16
From 2 to 4 :
Path: 2-->1-->5-->4
Total cost : 17
*/
int main() {
#ifndef ONLINE_JUDGE
freopen("HDU1385.in", "r", stdin);
#endif
while (cin >> n, n) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
cin >> g[i][j];
if (g[i][j] == -1) g[i][j] = INF;
path[i][j] = j;
}
for (int i = 1; i <= n; i++) cin >> w[i];
floyd();
int s, e;
while (cin >> s >> e, ~s && ~e) {
printf("From %d to %d :\n", s, e);
printf("Path: %d", s);
if (s != e) print(s, e); // 起点与终点不同开始递归
printf("\nTotal cost : %d\n\n", g[s][e]);
}
}
return 0;
}