3790:最短路径问题(HDU)

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
 
Source
哎,终于出来了
 1 #include<iostream>
 2 #include<map>
 3 #include<cstdio>
 4 using namespace std;
 5 #define inf 1000000000
 6 int s, t;
 7 int n, m,k;
 8 struct  di
 9 {
10     int s, money;
11 }dis[1010];
12 struct e
13 {
14     int from, to, distance, cost;
15 }es[100010];
16 void ds()
17 {
18     dis[s].s = 0;
19     while (true)
20     {
21         bool update = false;
22         for (int i = 0; i < k; i++)
23         {
24             if (dis[es[i].from].s != inf && (dis[es[i].to].s > dis[es[i].from].s + es[i].distance ))
25             {
26                 dis[es[i].to].s = dis[es[i].from].s + es[i].distance;
27                 dis[es[i].to].money = dis[es[i].from].money + es[i].cost;
28                 update = true;
29             }
30             else if(dis[es[i].to].s == dis[es[i].from].s + es[i].distance&&dis[es[i].to].money > dis[es[i].from].money + es[i].cost)
31             {
32                 dis[es[i].to].s = dis[es[i].from].s + es[i].distance;
33                 dis[es[i].to].money = dis[es[i].from].money + es[i].cost;
34             }
35         }
36         if (!update) break;
37     }
38     printf("%d %d
", dis[t].s, dis[t].money);
39 }
40 int main()
41 {
42     while (cin >> n >> m, n != 0 && m != 0)
43     {
44         k = 0;
45         for (int i = 0; i < m; i++)
46         {
47             int a, b, c, d;
48             scanf("%d %d %d %d", &a,&b,&c,&d); 
49             es[k].from = a, es[k].to = b, es[k].distance = c, es[k++].cost = d;
50             es[k].from = b, es[k].to = a, es[k].distance = c, es[k++].cost = d;
51         }
52         for (int i = 0; i <= n; i++)
53         {
54             dis[i].s = inf;
55             dis[i].money = 0;
56         }
57         scanf("%d %d", &s, &t);
58         ds();
59     }
60     return 0;
61 }
 

这是网上大佬的方法,为方便复习,拿来用了;

思路是djkstra的算法,当时我也想用了的,就是不太清楚cost给怎么定义,所以就用了bellman-ford,下次用队列优化的bellman-ford试试

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #define maxn 1007
 5 #define INF 65535
 6 using namespace std;
 7 
 8 int start,e;
 9 int n,m;
10 int map[maxn][maxn];
11 int cost[maxn][maxn];
12 
13 void Dijkstra()
14 {
15     int v,Min,vis[maxn];
16     int d[maxn],c[maxn];
17     for(int i = 1;i <= n;i++) {
18         d[i] = map[start][i];
19         c[i] = cost[start][i];
20     }
21     memset(vis,0,sizeof(vis));
22     vis[start] = 1;
23     for(int i = 1;i <= n;i++)
24     {
25         if(vis[e]) break;
26         Min = INF;
27         for(int j = 1;j <= n;j++) 
28             if(!vis[j] && d[j]<Min)
29                 Min = d[v=j];
30         vis[v] = 1;
31         for(int j = 1;j <= n;j++) 
32             if(!vis[j] && map[v][j]<INF) {
33                 if(d[j] > d[v]+map[v][j]) {
34                     d[j] = d[v]+map[v][j];
35                     c[j] = c[v]+cost[v][j];
36                 }
37                 else if(d[j] == d[v]+map[v][j]) 
38                     if(c[j] > c[v]+cost[v][j])
39                         c[j] = c[v]+cost[v][j];
40             }
41     }
42     printf("%d %d
",d[e],c[e]);
43 }
44 
45 int main()
46 {
47     while(scanf("%d%d",&n,&m) && n+m)
48     {
49         for(int i = 1;i <= n;i++)
50             for(int j = 1;j <= n;j++) {
51                 map[i][j] = i==j?0:INF;
52                 cost[i][j] = i==j?0:INF;
53             }
54         int a,b,c,d;
55         for(int i = 1;i <= m;i++)
56         {
57             scanf("%d%d%d%d",&a,&b,&c,&d);
58             if(map[a][b]>c)
59             {
60                 map[a][b]=map[b][a]=c;
61                 cost[a][b]=cost[b][a]=d;
62             }
63             else if(map[a][b]==c)
64             {
65                 if(cost[a][b]>d)
66                 cost[a][b]=cost[b][a]=d;
67             }
68         }
69         scanf("%d%d",&start,&e);
70         Dijkstra();
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/kangdong/p/8854041.html