垃圾学渣求毕业 2021-12-05 08:56 采纳率: 50%
浏览 223
已结题

算法题求解!最短路径+动态规划 C++

题目设计:
你怀疑你的导航系统有时会选择低效的路线。
所以你决定收集一些关于你所在地区的道路系统的数据并编写一个程序,计算出从你的家到你所在地区的最短(综合道路长度)和最快(预期旅行时间)的路线。
为了使这一任务易于管理,你想出了一个简单的模型。道路系统道路系统由路口(数字从1到N)和连接它们的道路组成,每条道路都有一个限速(单位:km/h)和一个长度(单位:km)。
在其中一个路口转换道路既不耗费时间也不耗费距离。
为了简单起见,你还假设所有的道路都是双向的,并且你可以一直以限速行驶。

输入的内容包括

  • 一行包含N和M(2 ≤ N ≤ 5 · 10^4^, 1 ≤ M ≤ 2 · 10^5^) --分别表示路口和道路的数量
  • M行描述道路,第 i 行包含bi, ei, vi和 i (1 ≤ bi,ei≤N,20≤vi≤150,1≤ i ≤300)分别代表第i条道路,与其连接的路口,速度限制和长度(所有这些输入都是整数)
  • 一行包含 Q(1 ≤ Q ≤ 1000)--查询的数量
  • Q行给出查询,每行包括一个整数 j:目的地路口的索引和一个字符c∈{'s', 'f'}

输出

  • 对于's'类型的查询,输出从你的家(1号路口)到指定目的地的最短路线的长度。
  • 对于'f'类型的查询,输出从你的家到指定目的地的最短旅行时间(假设一直按限速行驶),精度为10^-3^
  • 使用与输入相同的单位,用空格分隔数量和单位。如果一个给定的目的地不能到达,输出 "IMPOSSIBLE"。

例如:

img

第三组:
20 80
19 15 57 179
20 20 125 175
5 4 60 34
9 10 24 85
18 8 114 244
19 9 23 245
1 5 115 132
7 17 45 117
6 12 24 109
1 12 116 83
3 3 83 270
20 20 145 65
9 13 78 47
11 14 40 152
9 15 79 70
18 9 72 101
19 5 105 282
2 3 120 90
20 13 105 186
2 4 72 145
13 18 103 90
1 3 26 143
19 13 45 7
5 14 39 295
9 7 74 218
15 5 73 131
6 15 79 255
6 15 56 113
14 5 40 157
17 17 57 216
17 14 106 260
18 9 121 201
7 11 76 25
14 17 20 144
10 6 49 285
6 16 88 95
6 4 82 96
10 16 121 187
19 11 100 294
6 9 129 241
4 4 90 99
11 15 79 130
5 8 95 108
19 15 29 285
19 20 122 280
19 13 76 13
12 16 67 88
18 10 107 56
2 18 147 300
6 15 27 130
16 6 80 28
8 5 101 96
16 16 76 130
12 3 134 1
17 4 145 284
14 9 24 203
5 13 39 140
12 9 116 254
5 12 141 52
16 3 68 95
17 1 44 14
12 20 62 161
18 16 129 72
16 18 117 114
20 17 128 271
2 1 92 255
1 19 74 115
15 2 57 240
18 7 41 140
14 1 107 280
4 6 66 205
6 10 60 209
17 2 112 42
8 2 45 14
7 16 59 33
13 16 40 270
17 6 41 59
4 13 57 245
19 11 55 97
2 8 115 80
10
2 s
15 f
7 s
17 f
8 f
9 f
17 s
16 f
2 s
3 f

输出:
56 km
2.87883212 h
131 km
0.31818182 h
1.00429293 h
2.31217371 h
14 km
2.02895008 h
56 km
0.72297993 h

关于这道题应该要用到Dijkstra算法或者Moore-Bellman-Ford 算法?希望可以给个详细点的代码,谢谢!
学到的算法如下代码

void dijkstra_set (int s, int n) {
    fill (d, d + n + 1, INF ) ;
    d[s] = 0;

    set <pair <int , int > > dst ;
    dst . insert ({d[s], s}) ;

    while (! dst. empty () ) {
        int v = dst . begin () -> second ;
        dst . erase ( dst . begin () );
        for ( auto e: edges [v])
              if (d[v] + e. cost < d[e.u]) {
                  dst . erase ({d[e.u], e.u}) ;
                  d[e.u] = d[v] + e. cost ;
                  dst . insert ({d[e.u], e.u}) ;
              }
     }
}
  • 写回答

3条回答 默认 最新

  • Clarence Liu 2021-12-09 08:57
    关注
    
     
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e5 + 100;
    struct Edge{
        int next;
        int to;
        int len;
        int speed;
    }edge[MAXN];
    int cnt;
    int head[MAXN];
    void Add_Edge(int u, int v, int speed, int len){
        edge[cnt].next = head[u];
        edge[cnt].to = v;
        edge[cnt].speed = speed;
        edge[cnt].len = len;
        head[u] = cnt++;
    }
    int dis[MAXN];
    struct st{
        int id;
        int dis;
        bool operator < (const st &B)const{
            return dis > B.dis;
        }
    };
    int vis[MAXN];
    const int INF = 0x3f3f3f3f;
    void dijkstra(int s){
        dis[s] = 0;
        priority_queue<st> q;
        q.push(st{s, dis[s]});
        while(!q.empty()){
            auto u = q.top();
            q.pop();
            if(vis[u.id]) continue;
            vis[u.id] = 1;
            for(int i=head[u.id];~i;i=edge[i].next){
                int v = edge[i].to;
                if(!vis[v] && dis[u.id] + edge[i].len < dis[v]){
                    dis[v] = dis[u.id] + edge[i].len;
                    q.push(st{v, dis[v]});
                }
            }
        }
    }
    const double eps = 1e-10;
    int dcmp(double x){
        if(fabs(x) < eps) return 0;
        return x < 0 ? -1 : 1;
    }
    struct st2{
        int id;
        double t;
        bool operator < (const st2 &B)const{
            return dcmp(t - B.t) > 0;
        }
    };
    double dis2[MAXN];
    const double INF2 = 999999999.0;
    void dijkstra2(int s){
        dis2[s] = 0.0;
        priority_queue<st2> q;
        q.push(st2{s, dis2[s]});
        while(!q.empty()){
            auto u = q.top();
            q.pop();
            if(vis[u.id]) continue;
            vis[u.id] = 1;
            for(int i=head[u.id];~i;i=edge[i].next){
                int v = edge[i].to;
                if(!vis[v] && dcmp(dis2[v] - dis2[u.id] - edge[i].len * 1.0 / edge[i].speed) > 0){
                    dis2[v] = dis2[u.id] + edge[i].len * 1.0 / edge[i].speed;
                    q.push(st2{v, dis2[v]});
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int n, m;
        cin >> n >> m;
        memset(head, -1, sizeof head);
        memset(dis, 0x3f, sizeof dis);
        for(int i=0;i<m;i++){
            int u, v, speed, len;
            cin >> u >> v >> speed >> len;
            Add_Edge(u, v, speed, len);
            Add_Edge(v, u, speed, len);
        }
        int q;
        dijkstra(1);
        memset(vis, 0, sizeof vis);
        for(int i=0;i<=n;i++) dis2[i] = INF2;
        dijkstra2(1);
        cin >> q;
        while(q--){
            int j;
            char c;
            cin >> j >> c;
            if(c == 's'){
                if(dis[j] == INF) cout << "IMPOSSIBLE\n";
                else cout << dis[j] << ' ' << "km\n";
            }else{
                if(dcmp(dis2[j] - INF2) == 0) cout << "IMPOSSIBLE\n";
                else cout << fixed << setprecision(8) << dis2[j] << ' ' << "h\n";
            }
        }
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 12月19日
  • 已采纳回答 12月11日
  • 赞助了问题酬金 12月6日
  • 赞助了问题酬金 12月6日
  • 展开全部

悬赏问题

  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元