题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3790
题目大意:
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
解题思路:
在最短距离的基础上加上一个数组维护花费,每次更新时,先保持距离最短,在同等距离的时候保持花费最小。(注意有重边,更新最短距离和在该距离下的最小花费)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1000 + 10; 5 const int INF = 0x3f3f3f3f; 6 int Map[maxn][maxn]; 7 int Map1[maxn][maxn]; 8 int v[maxn], d[maxn], d1[maxn]; 9 int n, m; 10 void dijkstra(int s, int t) 11 { 12 memset(v, 0, sizeof(v)); 13 for(int i = 0; i <= n; i++)d[i] = (i == s ? 0 : INF); 14 for(int i = 0; i <= n; i++)d1[i] = (i == s ? 0 : INF); 15 for(int i = 0; i < n; i++) 16 { 17 int x, m = INF, m1 = INF; 18 for(int i = 1; i <= n; i++) 19 { 20 if(v[i])continue; 21 if(m > d[i]) 22 { 23 m = d[i]; 24 m1 = d1[i]; 25 x = i; 26 } 27 else if(m == d[i] && m1 > d1[i]) 28 { 29 m1 = d1[i]; 30 x = i; 31 } 32 } 33 v[x] = 1; 34 for(int i = 1; i <= n; i++) 35 { 36 if(v[i])continue; 37 if(d[i] > d[x] + Map[x][i]) 38 { 39 d[i] = d[x] + Map[x][i]; 40 d1[i] = d1[x] + Map1[x][i]; 41 } 42 else if(d[i] == d[x] + Map[x][i] && d1[i] > d1[x] + Map1[x][i]) 43 { 44 d1[i] = d1[x] + Map1[x][i]; 45 } 46 } 47 } 48 printf("%d %d ", d[t], d1[t]); 49 } 50 int main() 51 { 52 while(scanf("%d%d", &n, &m) != EOF && n) 53 { 54 int u, v, w, c; 55 memset(Map, INF, sizeof(Map)); 56 memset(Map1, INF, sizeof(Map1)); 57 while(m--) 58 { 59 scanf("%d%d%d%d", &u, &v, &w, &c); 60 if(Map[u][v] > w) 61 { 62 Map[u][v] = Map[v][u] = w; 63 Map1[u][v] = Map1[v][u] = c; 64 } 65 else if(w == Map[u][v] && Map1[u][v] > c) 66 { 67 Map1[u][v] = Map1[v][u] = c; 68 } 69 } 70 scanf("%d%d", &u, &v); 71 dijkstra(u, v); 72 } 73 }