题目:http://acm.hdu.edu.cn/showproblem.php?pid=1385
Input
First is N, number of cities. N = 0 indicates the end of input.
The data of path cost, city tax, source and destination cities are given in the input, which is of the form:
a11 a12 ... a1N
a21 a22 ... a2N
...............
aN1 aN2 ... aNN
b1 b2 ... bN
c d
e f
...
g h
where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:
The data of path cost, city tax, source and destination cities are given in the input, which is of the form:
a11 a12 ... a1N
a21 a22 ... a2N
...............
aN1 aN2 ... aNN
b1 b2 ... bN
c d
e f
...
g h
where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:
Output
From c to d :
Path: c-->c1-->......-->ck-->d
Total cost : ......
......
From e to f :
Path: e-->e1-->..........-->ek-->f
Total cost : ......
Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
Path: c-->c1-->......-->ck-->d
Total cost : ......
......
From e to f :
Path: e-->e1-->..........-->ek-->f
Total cost : ......
Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
Sample Input
5 0 3 22 -1 4 3 0 5 -1 -1 22 5 0 9 20 -1 -1 9 0 4 4 -1 20 4 0 5 17 8 3 1 1 3 3 5 2 4 -1 -1 0
Sample Output
From 1 to 3 :
Path: 1-->5-->4-->3
Total cost : 21
From 3 to 5 :
Path: 3-->4-->5
Total cost : 16
From 2 to 4 :
Path: 2-->1-->5-->4
Total cost : 17
Source
Recommend
一上午也没干啥, 就看这道题了, 也确实发现最短路白学了, 水平仅限于敲模板。但更说明一个问题, 我要Fighting!! 题目要打印路径、 输出最少费用(过路费和运费)。
ac码:
//Floyd更新最短路时用到了动规思想, #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int INF = 0x3f3f3f3f; int map[100][100], Tax[100], Result[100][100]; //Result 记录路径; int n; void Floyd() { for(int i = 1; i <= n; i++) //初始化为列; for(int j = 1; j <= n; j++) Result[i][j] = j; for(int k = 1; k <= n; k++) for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { int Q = map[i][k] + map[k][j] + Tax[k]; if(map[i][j] > Q) { map[i][j] = Q; Result[i][j] = Result[i][k]; //更新路径; } if(map[i][j] == Q) { if(Result[i][j] > Result[i][k]) Result[i][j] = Result[i][k]; //字典序; } } } int main() { while(~scanf("%d", &n), n) { int M, j = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { scanf("%d", &M); if(M == -1) map[i][j] = INF; else map[i][j] = M; } for(int i = 1; i <= n; i++) scanf("%d", &Tax[i]); Floyd(); int a, b; while(~scanf("%d %d", &a, &b)) { if(j != 0) printf(" "); if(a == -1 && b == -1) break; printf("From %d to %d : ", a, b); printf("Path: %d", a); int t = a; while(t != b) { printf("-->%d", Result[t][b]); t = Result[t][b]; } j++; printf(" Total cost : %d ", map[a][b]); } //printf(" "); } return 0; }
思路是对的:
//但为啥一直TLE, 数组都换成x[10][10]了还是不行; #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int INF = 0x3f3f3f3f; int Map[10][10], map[10][10]; int dis[10], vis[10], pre[10], Tax[10], Result[10]; int n; void Dijkstra(int src) { // memset(pre, -1, sizeof(pre)); memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) { dis[i] = map[src][i]; if(dis[i] != INF) pre[i] = src; //记录前驱; else pre[i] = 0; } vis[src] = 1; for(int i = 1; i < n; i++) { int temp = src, min = INF; for(int j = 1; j <= n; j++) { if(!vis[j] && dis[j] < min) { temp = j; min = dis[j]; } } vis[temp] = 1; for(int j = 1; j <= n; j++) if(!vis[j] && map[temp][j] < INF) { if(dis[j] > dis[temp] + map[temp][j]) { dis[j] = dis[temp] + map[temp][j]; pre[j] = temp; //更新 } else if(dis[j] == dis[temp] + map[temp][j]) { if(pre[j] > temp) pre[j] = temp; //更新前驱; } } } } int main() { while(~scanf("%d", &n), n) { for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { cin >> Map[i][j]; if(Map[i][j] == -1 || !Map[i][j]) Map[i][j] = INF; } for(int i = 1; i <= n; i++) scanf("%d", &Tax[i]); int a, b; while(~scanf("%d %d", &a, &b)) { if(a == -1 && b == -1) break; int Q = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(j == a || j == b) map[i][j] = Map[i][j]; else map[i][j] = Map[i][j] + Tax[j]; } Dijkstra(a); int t = pre[b]; while(t != a) //数组模拟回溯过程; { Result[Q++] = t; t = pre[t]; } printf("From %d to %d : ", a, b); printf("Path: %d", a); for(int I = Q -1; I >= 0; I--) printf("-->%d", Result[I]); //It's cool printf("-->%d ", b); printf("Total cost : %d ", dis[b]); printf(" "); } } return 0; }