数据结构实验之图论七:驴友计划

 

Problem Description

做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。

Input

连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。 

Output

在同一行中输出路径长度和收费总额,数据间用空格间隔。 

Sample Input

1
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output

3 40
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define INF 0x3f3f3f3f
  4. #define MAXN 510
  5. int mp[MAXN][MAXN];
  6. int cost[MAXN][MAXN];
  7. int dis[MAXN];  //原点v0到vi最短路径长度
  8. int vis[MAXN];  //标记数组
  9. int mon[MAXN];
  10. void Dijkstra(int n, int v0, int vn)
  11. {
  12.     int i, j;
  13.     for(i = 0; i < n; i++)
  14.     {
  15.         dis[i] = mp[v0][i];
  16.         mon[i] = cost[v0][i];
  17.     }
  18.     memset(vis, 0, sizeof(vis));
  19.     vis[v0] = 1;
  20.     dis[v0] = 0;
  21.     mon[v0] = 0;
  22.     for(i = 1; i < n; i++)
  23.     {
  24.         int Min = INF;
  25.         int k = v0;
  26.         for(j = 0; j < n; j++) //选择当前集合中最短路径的顶点k
  27.         {
  28.             if(!vis[j] && dis[j] < Min)
  29.             {
  30.                 Min = dis[j];
  31.                 k = j;
  32.             }
  33.         }
  34.         vis[k] = 1;
  35.         for(j = 0; j < n; j++)
  36.         {
  37.             if(!vis[j] && mp[k][j] < INF)
  38.             {
  39.                 if(dis[k] + mp[k][j] < dis[j])
  40.                 {
  41.                     dis[j] = dis[k] + mp[k][j];
  42.                     mon[j] = mon[j] + cost[k][j];
  43.                 }
  44.             }
  45.             else if(dis[k] + mp[k][j] == dis[j] && mon[k] + cost[k][j] < mon[j])
  46.                 mon[j] = mon[j] + cost[k][j];
  47.         }
  48.     }
  49.     printf("%d %d\n", dis[vn], mon[vn]);
  50. }
  51. int main()
  52. {
  53.     int t, n, m, s, d, a, b, l, c;
  54.     int i, j;
  55.     scanf("%d", &t);
  56.     while(t--)
  57.     {
  58.         scanf("%d%d%d%d", &n, &m, &s, &d);
  59.         for(i = 0; i < n; i++)
  60.             for(j = 0; j < n; j++)
  61.             if(i == j) mp[i][j] = 0;
  62.             else mp[i][j] = INF;
  63.         for(i = 0; i < m; i++)
  64.         {
  65.             scanf("%d%d%d%d", &a, &b, &l, &c);
  66.             mp[a][b] = mp[b][a] = l;
  67.             cost[a][b] = cost[b][a] = c;
  68.         }
  69.         Dijkstra(n, s, d);
  70.     }
  71. }
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值