zoukankan      html  css  js  c++  java
  • P3623 [APIO2008]免费道路

    P3623 [APIO2008]免费道路

    WQS二分题解。(好像可以不用这个做法)

    就是给每个点随一个权值,然后跑正常的WQS二分。

    (l, r) 可以是浮点数。

    时间 (O(n log^2n))

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10;
    
    ll N, M, K, fa[MAXN], vis[MAXN];
    double ans = 1e99;
    
    struct edge {
        ll x, y, c, id;
        double w;
        friend bool operator < (edge a, edge b) {return a.w == b.w ? a.c < b.c : a.w < b.w;}
    } E[MAXN];
    
    bool cmp(edge, edge);
    ll check(double);
    ll find_(ll);
    
    int main() {
    	srand(time(0));
        scanf("%lld%lld%lld", &N, &M, &K);
        for (ll i = 1; i <= M; i++) {
            scanf("%lld%lld%lld", &E[i].x, &E[i].y, &E[i].c);
            E[i].w = rand() % M; E[i].id = i;
        }
        double l = -1e8, r = 1e8;
        while (r - l >= 1e-5) {
            double mid = (l + r) / 2.0;
            ll num = check(mid);
            if (num > K) l = mid + 1;
            else if (num == K) {l = mid + 1, ans = mid; break;} 
            else r = mid - 1;
        }
        if (ans == 1e99) {
        	puts("no solution");
    		return 0;
    	}
    	sort(E+1, E+M+1, cmp);
        for (ll i = 1; i <= M; i++)
            if (vis[i])
                printf("%lld %lld %lld
    ", E[i].x, E[i].y, E[i].c);
        return 0;
    }
    
    bool cmp(edge a, edge b) {return a.id < b.id;}
    
    ll check(double now) {
        for (ll i = 1; i <= N; i++) fa[i] = i;
        for (ll i = 1; i <= M; i++) {
    		if (!E[i].c) E[i].w += now;
    		vis[i] = 0;
    	}
        sort(E+1, E+M+1);
        ll ret = 0;
        for (ll i = 1, cnt = 1; cnt < N && i <= M; i++) {
            ll fx = find_(E[i].x), fy = find_(E[i].y);
            if (fx != fy) {
                cnt++;
                fa[fx] = fy;
                ret += (E[i].c == 0 ? 1 : 0);
                vis[E[i].id] = 1;
            }
        }
        for (ll i = 1; i <= M; i++) if (!E[i].c) E[i].w -= now;
        return ret;
    }
    
    ll find_(ll x) {return fa[x] == x ? x : fa[x] = find_(fa[x]);}
    
  • 相关阅读:
    寻找——无限游戏破关(一)
    运维入职梳理文档
    seafile 旧版本升级新版本时python库引用报错
    操作系统-计算进程的物理地址(例题)
    拉取微信公众号视频文件
    洛谷-P3654 First Step (ファーストステップ)
    洛谷-P3392 涂国旗
    洛谷-P1706 全排列问题
    洛谷-P1157 组合的输出
    洛谷-P2241 统计方形(数据加强版)
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13904550.html
Copyright © 2011-2022 走看看