需要处理好字典序最小的路径
HDU1385(ZOJ1456)-Minimum Transport
//Hdu1385-ZOJ1456 //给定邻接矩阵,求给定起点到终点的最短路径,若有相同路长的路径按照字典序输出 //Floyd比较适合此题 //网上看到的两种做法比较推荐 //第一种是Floyd+记录起点后继 //第二种是Floyd+深搜(从起点开始深搜至终点)-利用Floyd得到的最短路剪枝 //其他的解法则是按照SPFA,dijkstra解,当路长相同时需要进行比较(较繁琐) //Time:0Ms Memory:404K #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int n; int d[MAX][MAX]; int board[MAX][MAX], c[MAX]; int path[MAX][MAX]; //记录i到j最短路径中i的后继 void floyd() { memcpy(d, board, sizeof(d)); 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] + c[k]) { d[i][j] = d[i][k] + d[k][j] + c[k]; path[i][j] = path[i][k]; } //相同路径下选择后继更小的 else if (d[i][j] == d[i][k] + d[k][j] + c[k] && path[i][j] > path[i][k]) path[i][j] = path[i][k]; } } void output(int s,int e) { printf("-->%d", path[s][e]); if (path[s][e] != e) output(path[s][e], e); } int main() { while (scanf("%d", &n), n) { for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { scanf("%d", &board[i][j]); if (board[i][j] == -1) board[i][j] = INF; path[i][j] = j; } for (int i = 1; i <= n; i++) scanf("%d", &c[i]); floyd(); int s, e; while (scanf("%d%d", &s, &e), s != -1 && e != -1) { printf("From %d to %d :\n", s, e); printf("Path: %d", s); if(s != e) output(s, e); //起点与终点不同开始递归 printf("\nTotal cost : %d\n\n", d[s][e]); } } return 0; }