• Codeforces 1023F Mobile Phone Network 思维


    Mobile Phone Network

    先把k个边加进去, 然后用m条边从小到达能加就加, 那么对于m条边中剩余的那些边(u, v, w)

    只有在树形成的路径(u, v)上存在一条比w大的边才能放进去, 那么路径(u, v)上所有边小于等于w

    用每条边更新一次用并查集维护, 用st表压标记可能会T。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PII pair<int, int>
    using namespace std;
    
    const int N = (int)5e5 + 7;
    const int inf = 0x3f3f3f3f;
    
    int n, k, m, id[N], val[N], pa[N], depth[N];
    vector<PII> G[N];
    vector<pair<PII, int>> V;
    
    int fa[N];
    int getRoot(int x) {
        return fa[x] == x ? x : fa[x] = getRoot(fa[x]);
    }
    bool unite(int x, int y) {
        x = getRoot(x);
        y = getRoot(y);
        if(x == y) return false;
        fa[y] = x;
        return true;
    }
    
    void dfs(int u, int fa) {
        depth[u] = depth[fa] + 1;
        pa[u] = fa;
        for(auto &e : G[u]) {
            if(e.se == fa) continue;
            id[e.se] = e.fi;
            dfs(e.se, u);
        }
    }
    
    int main() {
        scanf("%d%d%d", &n, &k, &m);
        for(int i = 1; i <= n; i++) fa[i] = i;
        for(int i = 1; i <= k; i++) val[i] = inf;
        for(int i = 1; i <= k; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(mk(i, v));
            G[v].push_back(mk(i, u));
            unite(u, v);
        }
        for(int i = 1; i <= m; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            if(unite(u, v)) {
                G[u].push_back(mk(0, v));
                G[v].push_back(mk(0, u));
            }
            else {
                V.push_back(mk(mk(u, v), w));
            }
        }
        dfs(1, 0);
        for(int i = 1; i <= n; i++) fa[i] = i;
        for(auto &t : V) {
            int u = t.fi.fi, v = t.fi.se, w = t.se;
            u = getRoot(u);
            v = getRoot(v);
            while(u != v) {
                if(depth[u] >= depth[v]) val[id[u]] = w, unite(pa[u], u);
                else val[id[v]] = w, unite(pa[v], v);
                u = getRoot(u);
                v = getRoot(v);
            }
        }
        LL ans = 0;
        for(int i = 1; i <= k; i++) {
            if(val[i] >= inf) {
                puts("-1");
                return 0;
            }
            ans += val[i];
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    console.dir()和console.log()的区别
    md5
    sorket is closed
    箱形图和小提琴图
    PCA降维
    模式识别与机器学习(二)
    模式识别与机器学习(一)
    论文研读Unet++
    分类中使用的一些评价指标
    前列腺分割论文
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11770608.html
Copyright © 2020-2023  润新知