• 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 }
  • 相关阅读:
    Oracle中使用游标详解
    arc140 vp 记录
    CF1710D Recover theTree
    2022.8 做题记录
    21noip赛前20天 day10 简要题解
    2022.7.22 AGC028F&CF1463F&P7740
    arc141 vp 记录
    2022.7.25 AGC027F&AGC032F&AGC013F
    2022.7.21 AGC046D&P6790&AGC041F
    2022.7.20 AGC052D&P4338&AGC033E
  • 原文地址:https://www.cnblogs.com/kangdong/p/8854041.html
Copyright © 2020-2023  润新知