• POJ-3662 通信线路


    摘要:简单来讲就是在无向图上求出一条从1到N的路径,使路径上第K+1大的边权尽量小。

    第K大的尽量小,这种表述就容易让人想到二分。

    蓝书上的解释:因为支付的钱更多时,合法的升级方案一定有包含子花费更少的升级方案,所以答案具有单调性。

    那么我们只要把权值大于mid的路径权值设为1,小于mid的置为0,求1到n的最短路是否不超过n即可。

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #pragma GCC optimize(2)
    
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> PII;
    
    
    const int N = 2e4 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f;
    int e[N], h[N], ne[N], w[N], d[N];
    int n, p, k, idx, ans;
    bool vis[N];
    
    priority_queue< PII, vector<PII>, greater<PII> > q;
    
    void init() {
        memset(h, -1, sizeof h);
        memset(d, 0x3f, sizeof d);
        memset(vis, false, sizeof vis);
    }
    
    void add(int a, int b, int c) {
        e[idx] = b;
        w[idx] = c;
        ne[idx] = h[a];
        h[a] = idx++;
        return ;
    }
    
    int dij(int mid) {
        memset(d, 0x3f, sizeof d);
        memset(vis, false, sizeof vis);
        d[1] = 0;
        q.push(make_pair(0, 1));
        
        while (!q.empty()) {
            int x = q.top().second;
            q.pop();
            if (vis[x]) continue;
            else vis[x] = 1;
            
            for (int i = h[x]; i != -1; i = ne[i]) {
                int y = e[i], z = w[i];
                
                if (z > mid) z = 1;
                else z = 0;
                
                if (d[x] + z < d[y]) {
                    d[y] = d[x] + z;
                    q.push(make_pair(d[y], y));
                }
            }
        }
        return d[n];
    }
    
    int main()
    {
        init();
        cin >> n >> p >> k;
        int ed = -INF;
        while (p--) {
            int x, y, z;
            cin >> x >> y >> z;
            add(x, y, z);
            add(y, x, z);
            ed = max(ed, z);
        }
        
        
        if(dij(0) == INF) {
            printf("-1
    ");
        } else {
            int ll = 0, rr = ed;
            int mid;
            while (ll <= rr) {
    //            cout << rr << endl;
                int mid = (ll + rr) / 2;
                if (dij(mid) <= k) {
                    ans = mid;
                    rr = mid - 1;
                } else {
                    ll = mid + 1;
                }
            }
            cout << ans << endl;
        }
            
    }
  • 相关阅读:
    java 测试 (junit+ junit 断言 + postman)
    junit 运行(eclipse + IDEA)
    junit 常用注解 + junit 断言详解
    工作周报模板
    spring boot tomcat 部署
    spring boot 集成JSP
    spring boot 集成 Mybatis,JPA
    JPA 常用注解
    员工年终绩效考核表模板
    2013 Noip提高组 Day1
  • 原文地址:https://www.cnblogs.com/mwh123/p/11704872.html
Copyright © 2020-2023  润新知