参考:https://www.cnblogs.com/qiufeihai/archive/2012/03/15/2398455.html
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2622 Accepted Submission(s): 825
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)
(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
注意点: 题中所给的输入数据有可能有多条长度相等,但花费不同的数据,在输入处理的时候需要进行判断,选出花费最少的情况!
1 #include <stdio.h> 2 #include <iostream> 3 #include <cstring> 4 #include <vector> 5 #include <algorithm> 6 #include <sstream> 7 8 #define INF 1000000000 9 10 using namespace std; 11 12 int dis[1002]; 13 int vis[1002]; 14 int cost[1002]; 15 int n, m; 16 17 struct node 18 { 19 int len; 20 int cost; 21 }g[1002][1002]; 22 23 void dijkstra(int start) 24 { 25 for(int i = 1; i <= n; ++i) 26 { 27 dis[i] = INF; 28 cost[i] = INF; 29 } 30 dis[start] = 0; 31 cost[start] = 0; 32 33 while(1) 34 { 35 int mark = -1, minDis = INF; 36 for(int i = 1; i <= n; ++i) 37 { 38 if(!vis[i] && dis[i] < minDis) 39 { 40 minDis = dis[i]; 41 mark = i; 42 } 43 } 44 45 if(mark == -1) 46 break; 47 vis[mark] = 1; 48 49 for(int i = 1; i <= n; ++i) 50 { 51 if(!vis[i]) 52 { 53 if(dis[mark] + g[mark][i].len < dis[i]) 54 { 55 dis[i] = dis[mark] + g[mark][i].len; 56 cost[i] = cost[mark] + g[mark][i].cost; 57 } 58 else if(dis[mark] + g[mark][i].len == dis[i] && cost[i] > cost[mark] + g[mark][i].cost) 59 { 60 cost[i] = cost[mark] + g[mark][i].cost; 61 } 62 63 64 65 } 66 } 67 68 } 69 } 70 71 int main() 72 { 73 while(scanf("%d %d", &n, &m) != EOF) 74 { 75 if(n == 0 && m == 0) 76 break; 77 78 memset(vis, 0, sizeof(vis)); 79 for(int i = 1; i <= n; ++i) 80 for(int j = 1; j <= n; ++j) 81 { 82 if(i == j) 83 g[i][j].len = 0; 84 else 85 g[i][j].len = INF; 86 } 87 88 int a, b, d, p; 89 for(int i = 1; i <= m; ++i) 90 { 91 scanf("%d %d %d %d", &a, &b, &d, &p); 92 /* g[a][b].len = g[b][a].len = d; 93 g[a][b].cost = g[b][a].cost = p;*/ //这样写会出错,必须下面那样写,因为有可能有长度相同但花费不同的边 94 95 if(g[a][b].len > d) 96 { 97 g[a][b].len = g[b][a].len = d; 98 g[a][b].cost = g[b][a].cost = p; 99 } 100 101 // 这里很重要!! 102 if(g[a][b].len == d && g[a][b].cost > p) // 如果长度相等,则存放较少的费用 103 { 104 g[a][b].cost = g[b][a].cost = p; 105 } 106 } 107 108 int s, t; 109 scanf("%d %d", &s, &t); 110 dijkstra(s); 111 112 cout << dis[t] << " " << cost[t] << endl; 113 } 114 115 return 0; 116 }