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\n", ans);
    return 0;
}

 

posted @ 2019-10-31 13:06  NotNight  阅读(183)  评论(0编辑  收藏  举报