最短路径问题 HDU

参考: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)
 

 

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 }
原文地址:https://www.cnblogs.com/FengZeng666/p/11246108.html