HDU - 最短路徑問題
阿新 • • 發佈:2018-11-03
http://acm.hdu.edu.cn/showproblem.php?pid=3790
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
Input
輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點。n和m為0時輸入結束。
(1<n<=1000, 0<m<100000, s != t)
Output
輸出 一行有兩個數, 最短距離及其花費。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
Problem solving report:
Description: 最短路問題,給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
Problem solving: 在最短路的基礎上加一個記錄兩個點的花費額的陣列,只存兩個點最小的花費額,在利用最短邊鬆弛其它邊的時候,若鬆弛後的邊不變,鬆弛最小的花費額。
#include <stdio.h> const int inf = 99999999; int n, m, s, t, k, a, b, d, q, minn; int vis[1010], dis[1010], map[1010][1010], cost[1010][1010]; int main() { while (scanf("%d%d", &n, &m), m + n) { for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i != j) cost[i][j] = cost[j][i] = map[i][j] = map[j][i] = inf; else cost[i][j] = cost[j][i] = map[i][j] = map[j][i] = 0; for (int i = 0; i < m; i++) { scanf("%d%d%d%d", &a, &b, &d, &q); if (map[a][b] > d) { map[a][b] = map[b][a] = d; cost[a][b] = cost[b][a] = q; } else if (map[a][b] == d && cost[a][b] > q) cost[a][b] = cost[b][a] = q; } scanf("%d%d", &s, &t); for (int i = 1; i <= n; i++) { dis[i] = map[s][i]; vis[i] = 0; } vis[s] = 1; for (int i = 1; i < n; i++) { minn = inf; for (int j = 1; j <= n; j++) { if (!vis[j] && dis[j] < minn) { k = j; minn = dis[j]; } } vis[k] = 1; for (int j = 1; j <= n; j++) { if (map[k][j] < inf) { if (!vis[j] && dis[j] > dis[k] + map[k][j]) { dis[j] = dis[k] + map[k][j]; cost[s][j] = cost[s][k] + cost[k][j]; } else if (!vis[j] && dis[j] == dis[k] + map[k][j] && cost[s][j] > cost[s][k] + cost[k][j]) cost[s][j] = cost[s][k] + cost[k][j]; } } } printf("%d %d\n", dis[t], cost[s][t]); } return 0; }