Minimum Transport Cost

题意很简单,有N个城市,两两之间的距离用一个邻接矩阵给出。问题关键在于,找出最短路,并输出字典序最小的一条。以前一直也没想过这个问题,没想过怎么把最短的一条输出来。其实也不较简单,就是先用Floyd求得点对距离,在按照字典序dfs,把最短距离作为一个强剪枝来用,得到的第一个合法路径即为最短最小字典序路径。路径的输出可以用递归的形式来实现。

 

代码
#include<stdio.h>
#include
<string.h>
#define INF 0xfffffff
#define NN 100
int N, S, T, ok;
int dis[NN][NN];
int map[NN][NN];
int mark[NN];
int pre[NN];
int cost[NN];
void floyd(){
int i, j, k;
memcpy(dis, map,
sizeof(map));
for (k = 1; k <= N; k++){
for (i = 1; i <= N; i++){
for (j = 1; j <= N; j++){
if (dis[i][j] > dis[i][k] + dis[k][j] + cost[k]){
dis[i][j]
= dis[i][k] + dis[k][j] + cost[k];
}
}
}
}
}

void dfs(int cur, int d){
int i, t;
if (d > dis[S][T]) return;
if (cur == T && d == dis[S][T]){
ok
= 1;
return;
}
for (i = 1; i <= N; i++){
if (!mark[i]){
mark[i]
= 1;
pre[i]
= cur;
t
= d + map[cur][i];
if (i != T){
t
+= cost[i];
}
dfs(i, t);
if (ok) return;
mark[i]
= 0;
}
}
}

void out(int cur){
if (cur == S){
printf(
"%d", cur);
return;
}
out(pre[cur]);
printf(
"-->%d", cur);
}
int main()
{
int i, j, a, b;
//freopen("q1456.in", "r", stdin);
//freopen("a.out", "w", stdout);
while(scanf("%d", &N) != EOF){
if (N == 0) break;
for (i = 1; i <= N; i++){
for (j = 1; j <= N; j++){
scanf(
"%d", &a);
if (a == -1) a = INF;
map[i][j]
= a;
}
}
for (i = 1; i <= N; i++){
scanf(
"%d", &cost[i]);
}
floyd();
while(scanf("%d%d", &a, &b) != EOF){
if (a == - 1 && b == -1) break;
S
= a;
T
= b;
ok
= 0;
memset(mark,
0, sizeof(mark));
dfs(S,
0);
printf(
"From %d to %d :\nPath: ", a, b);
out(b);puts("");
printf(
"Total cost : %d\n", dis[a][b]);
puts(
"");
}
}
return 0;
}

 

posted on 2010-08-02 20:50  ylfdrib  阅读(559)  评论(0编辑  收藏  举报