输出多源最短路径 但是要加上经过城市的tax 如果有多条 选择字典序最小那条
学习 floyd 和 path 记录的方法 path[i][j] 记录在i-j里面离i最近的那个节点
floyd其实很好用 但是时间复杂度有点高 但代码简单 曾经有spfa解这道题 总是有这样那样的小问题
代码非常麻烦 以后要看情况使用。。。


#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using std::sort; using std::queue; const int INF = 0x3f3f3f3f, MAXN = 1005; bool vis[MAXN]; int dis[MAXN], n, g[MAXN][MAXN], tax[MAXN]; int path[MAXN][MAXN]; int min(int a, int b) { return a<=b ?a :b ; } void floyd() { int i, k, j; 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++) { int tmp = g[i][k] + g[k][j] +tax[k]; //如果弄成inf为1<<30这里会溢出! if( tmp < g[i][j] ) { g[i][j] = tmp; path[i][j] = path[i][k]; } else if( tmp == g[i][j] ) path[i][j] = min(path[i][j], path[i][k]); } } int main() { int i, j, a, b, tmp; while(scanf("%d", &n), n!=0) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) { scanf("%d", &g[i][j]); if( g[i][j] == -1 ) g[i][j] = INF; } for(i=1; i<=n; i++) { scanf("%d", &tax[i]); } floyd(); while(scanf("%d %d", &a, &b)!=EOF) { if(a == -1 && b == -1) break; printf("From %d to %d :\n",a,b); printf("Path: %d",a); int k=a; while(k!=b) { printf("-->%d",path[k][b]); k=path[k][b]; } printf("\nTotal cost : %d\n\n",g[a][b]); } } return 0; }