您的位置:首页 > 其它

ZOJ-1456 Minimum Transport Cost 最短路floyd路径输出

2013-03-07 21:29 405 查看
这题难就难再要字典序输出,要是单单floyd的话,无法保证最后得到的路径字典序最小,一个简单的反例就是如果6 5 7 8 9和6 8 1 2 9以及6 10 1 2 9同时是6-9的最短路的话,如果忽略相等情况下的更新,6 8之间是不会被7作为中间节点而更新的,但是不忽略的话,又可能被中间比较大的节点更新了。所以直接floyd(采用path[i][j] = k表示i到j通过k点的方式还原路径)是不满足题意的。因此这里采用另外一种记录路径的方式,path[i][j]表示从i到j的第二个元素编号,那么由于仅仅只记录了第二个元素,因此当距离相等的时候,我们就只需要考虑新的“第二个元素”是否更优。这样可以避免将这个路径进行输出比较,如果距离相等,第二个元素相等,那么最后还原出来的路径就是一致的,无需更新。

代码如下:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

/*
相比于其他的最短路,这里只是多了一个节点上的信息
*/
int N;
int G[1005][1005]; // 由于题目中并没有说清楚数据范围,因此我们可以假设最大的内存
int path[1005][1005];  // 记忆路径
int dis[1005];   // 表示距离
int add[1005];   // 表示额外的节点附加值

void floyd() {
int reca[1005], recb[1005], idxa, idxb;
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= N; ++j) {
path[i][j] = j;
} // path[i][j]记录的是从i到j这条路的第二个元素
}
for (int k = 1; k <= N; ++k) {
for (int i = 1; i <= N; ++i) {
if (i == k || G[i][k] == -1) continue;
for (int j = 1; j <= N; ++j) {
if (j == k || G[k][i] == -1) continue;
if (G[i][k] != -1 && G[k][j] != -1) {
if(G[i][j] > G[i][k] + G[k][j] || G[i][j] == -1) {
G[i][j] = G[i][k] + G[k][j];
path[i][j] = path[i][k];
} else if (G[i][j] == G[i][k] + G[k][j]) {
if (path[i][j] > path[i][k]) {
// 由于记录的直接是第二个元素,所以只有当这个第二个元素小于已知值时才更新
path[i][j] = path[i][k];
}
}
}
}
}
}
}

void display(int x, int y) {
if (x != y) {
printf("-->%d", path[x][y]);
display(path[x][y], y);
}
}

int main() {
while (cin >> N, N) {
memset(path, 0xff, sizeof (path));
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) {
scanf("%d", &add[i]);
}
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= N; ++j) {
if (i == j || G[i][j] == -1) continue;
else G[i][j] += add[j];
} // 将节点信息直接附加在边上,这样就是起始点没有加上节点值
}
floyd();
int a, b, first;
while (scanf("%d %d", &a, &b), a!=-1 && b!=-1) {
first = 1;
printf("From %d to %d :\n", a, b);
printf("Path: %d", a);
display(a, b);
puts("");
printf("Total cost : %d\n\n", a!=b ? G[a][b]-add[b] : 0);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: