zoukankan      html  css  js  c++  java
  • 洛谷P1462通往奥格瑞玛的道路题解

    [题目]: https://www.luogu.org/problemnew/show/P1462

    题意

    题目是给定了一张双向边,有边权的图,然后让我们求出一个最小值,满足一条路径上的最大的费用小于这个最小值且这条路径的所损失的血量不超过总血量。

    思路

    往往这种求最大值的最小值一般就是二分,然后写个check函数来判断这个最小值是否满足条件,如果不满足条件,就扩大范围,而如果满足条件的话就缩小范围,直到满足条件。

    所以我们就可以二分一个值(h)(二分边界是起点的费用到所有点的费用最大值),跑最短路,并且在跑最短路的时候,每次松弛操作时,都要满只有费用<=(h)的点才可以进行松弛。但是这个点的坑点和数据太弱,建议做完了这道题可以去挑战一波数据加强版——

    做这个题的时候要注意每次二分时都需要判断u,v的费用是否满足条件,然后我们需要寻找到最大值,所以要使用不记录二分法。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    long long lin[1000100], data[1000100], vis[1000100];
    long long n, m, b, maxn, cnt, u, v;
    struct edge {
        long long from, to, len, nex;
    }e[200010];
    struct cym {
        long long len, num;
    }dis[1000010];
    bool operator < (cym a, cym b) 
    {
        return a.len > b.len;
    }
    inline void add(long long u, long long v, long long l)
    {
        e[++cnt].from = u;
        e[cnt].to = v;
        e[cnt].len = l;
        e[cnt].nex = lin[u];
        lin[u] = cnt;
    }
    using std :: priority_queue;
    using std :: max;
    priority_queue <cym> q;
    bool check(long long h)
    {
        memset(vis, 0, sizeof(vis));
        if (data[u] > h || data[v] > h)
            return false;
        for (int i = 1; i <= n; i++)
            dis[i].len = 2147483647, dis[i].num = i;
        dis[u].len = 0;
        q.push(dis[u]);
        while(!q.empty())
        {
            cym cur = q.top();
            q.pop();
        	if (vis[cur.num] || data[cur.num] > h)
        	continue;
            vis[cur.num] = 1;
            for (int i = lin[cur.num]; i; i = e[i].nex)
                if (dis[e[i].to].len > cur.len + e[i].len && data[e[i].to] <= h && !vis[e[i].to])
                {
                    dis[e[i].to].len = cur.len + e[i].len;
                        q.push(dis[e[i].to]);
                }
        }
        if (dis[v].len > b)
            return false;
        else
            return true;
    }
    inline void binary_search()
    {
        long long l = 1, r = maxn;
        long long mid = (l + r) >> 1;
        while (l <= r)
        {
            mid = (l + r) >> 1;
         	if (check(mid))
         	r = mid - 1;
         	else
            l = mid + 1;
        }
        if (l == 0)
        printf("-1");
        else
        printf("%lld", l);
    }
    signed main()
    {
    // 	freopen("roa.in", "r", stdin);
    // 	freopen("roa.out", "w", stdout);
        scanf("%lld%lld%lld%lld%lld", &n, &m, &u, &v, &b);
        for (long long i = 1; i <= n; i++)
            scanf("%d", &data[i]), maxn = max(maxn, data[i]);
        for (long long i = 1; i <= m; i++)
        {
            long long a, b, c;
            scanf("%lld%lld%lld", &a, &b, &c);
            add(a, b, c);
            add(b, a, c);
        }          
        if (!check(2147483647))
        {          
            printf("-1");
            return 0;
        }      
        binary_search();	
        return 0;                                                                   
    }
    
  • 相关阅读:
    java 调用Python
    RestController 能不能通过配置关闭
    java jdb
    Curator zookeeper
    「ASCII 流程图」工具——Graph Easy
    Python String Formatting Best Practices
    idea java9以及以上 出现找不到class的情况
    时间序列分析 异常分析 stl
    pip install whl
    t-SNE 层次聚类
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9901983.html
Copyright © 2011-2022 走看看