题目链接

floyd 字典序最小路径输出

距离松弛 : d[i][j] = d[i][k]+d[k][j]; 路径记录: p[i][j] = p[i][k];

如果距离相等,路径赋值取最小值 p[i][j] = min(p[i][j], p[i][k])。
路径输出: for(int i = u; i != v; i = p[i][v]) cout << p[i][v];

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <queue>

using namespace std;

const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int Maxn = 1000+10;

int G[Maxn][Maxn], p[Maxn][Maxn], cost[Maxn];

int main(void)
{
	int n;
	while(scanf("%d", &n) != EOF) {
		if(!n) break;
		for(int i = 1; i <= n; ++i) 
			for(int j = 1; j <= n; ++j) scanf("%d", &G[i][j]);
			
		for(int i = 1; i <= n; ++i) {
			for(int j = 1; j <= n; ++j) p[i][j] = j;
		}
		for(int i = 1; i <= n; ++i) scanf("%d", &cost[i]);
		
		for(int k = 1; k <= n; ++k) {
			for(int i = 1; i <= n; ++i) {
				for(int j = 1; j <= n; ++j) {
					if(G[i][k] == -1 || G[k][j] == -1 || i == k || j == k || i == j) continue;
					if(G[i][j] == -1 || G[i][j] > G[i][k]+G[k][j]+cost[k]) {
						G[i][j] = G[i][k]+G[k][j]+cost[k];
						p[i][j] = p[i][k];
					} else if(G[i][j] == G[i][k]+G[k][j]+cost[k] && p[i][j] > p[i][k]) 
						p[i][j] = p[i][k];
				}
			}
		}
		
		int u, v;
		while(1) {
			scanf("%d%d", &u, &v);
			int ans = G[u][v];
			if(u == -1 && v == -1) break;
			stack <int> sk;
			printf("From %d to %d :\n", u, v);
			printf("Path: %d", u);
			for(int i = u; i != v; i = p[i][v]) printf("-->%d", p[i][v]);
			printf("\nTotal cost : %d\n\n", ans);
		}
	}
	return 0;
}