游游出游 | Cpp 二分 + 最短路

游游出游

https://www.nowcoder.com/practice/e787b99f04c1498aa32b9430a4616d8a

题意

游游准备去开车旅行,她初始在1号城市,准备前往n号城市。游游打开了携程,她查询到了地图上有若干城市,城市之间有一些道路连接。每条道路有承重限制,当游游的车重量超过了承重时,她就不能走这条道路。游游是一个贪心的人,她希望总路程不超过h的前提下,携带尽可能多的物品出行。游游想知道,自己的车最多重量能达到多少?

思路

题目求的是 车的重量的最大值

单调性:如果车的重量为10时,可以走到终点,那么车的重量为5的时候也一定可以走到终点,因为车的重量减少后,可走的道路只多不少。

所以可以二分答案,考虑下如何check

当前的重量是x的话,对于每条道路u,v,w,如果w>=x的话,这条道路才能被作为可走的道路。不用每次重新建图,只需要在跑最短路的时候,这里用的是dijkstra,如果碰到当前的边的w<x,跳过当前边即可。起点是1,如果到终点的距离<=h的话,说明这个重量可以到达,就记录答案并且移动左端点,看能不能找到更大的重量

Cpp代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e6 + 10;

typedef pair<long long, long long> PII;

int n, m, maxVal;
int h[maxn], w[maxn], e[maxn], ne[maxn], idx,d[maxn];
long long dis[maxn];
bool st[maxn];

void add(int a, int b, int c,int dd) {
    e[idx] = b, w[idx] = c,d[idx] = dd, ne[idx] = h[a], h[a] = idx++;
}
bool dijkstra(int limit) {
    for (int i = 0; i <= n + 3; i++) {
        dis[i] = 1e18;
        st[i] = false;
    }
    dis[1] = 0;
    ///建立一个维护最小值的优先队列
    priority_queue<PII, vector<PII>, greater<PII>>heap;
    heap.push({0, 1}); ///起始点放入队列
    while (heap.size()) {
        auto t = heap.top(); ///最小值
        heap.pop();
        long long ver = t.second, dd = t.first;
        if (st[ver]) continue; ///该点更新
        st[ver] = true;
        for (int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if(w[i] < limit) {
                continue ;
            }
            if (dis[j] > dd + d[i]) {
                dis[j] = dd + d[i];
                heap.push({dis[j], j});
            }
        }
    }
    return dis[n] <= maxVal;
}


int main() {
    cin >> n >> m >> maxVal;
    memset(h, -1, sizeof h);
    for (int i = 1; i <= m; i++) {
        int u, v, w,dd;
        cin >> u >> v >> w >> dd;
        add(u, v, w,dd);
        add(v,u,w,dd);
    }
    int l = 0,r = 1e9,res =-1;
    while(l<=r) {
        int mid = (l+r+1) / 2;
        if (dijkstra(mid)) {
            res = mid ;
            l = mid + 1;
        }else{
            r = mid - 1;
        }
    }
    cout<<res;






    return 0;
}

#牛客创作赏金赛#
15天大厂真题带刷Go题解 文章被收录于专栏

15天大厂真题带刷Golang题解

全部评论

相关推荐

球球别再泡了:坏,我单9要了14
点赞 评论 收藏
分享
评论
2
收藏
分享
牛客网
牛客企业服务