1. 程式人生 > >CCC2018 最大戰略儲備

CCC2018 最大戰略儲備

並查集基本處理即可。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define int long long
const int MAXN = 100001;
struct edge {
    int u;
    int v;
    int w;
    bool tag;
}e[MAXN << 1];

bool cmp(edge a,edge b){
    return a.w < b.w;
}
int ans;
struct _set {
    int f[MAXN];
    int rnd[MAXN];
    _set() {
        memset(rnd,0,sizeof rnd);
    }
    int find(int x) {
        return x == f[x] ? x : f[x] = find(f[x]);
    }
    void merge(int x,int y) {
        if(rnd[x] > rnd[y]) {
            f[y] = x;
        }
        else if(rnd[x] == rnd[y]) {
            f[x] = y;
            rnd[y] ++;
        }
        else f[x] = y;
    }
}F1,F2;

int read () {
    int q=0,f=1;char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(isdigit(ch)){
        q=q*10+ch-'0';ch=getchar();
    }
    return q*f;
}

int n,m,p,q;
int tot;
int cnt1,cnt2;
signed main () {
    n = read(),m = read(),p = read(),q = read();
    for(int i = 1;i <= p; ++i) {
        e[i].u = read();
        e[i].v = read();
        e[i].w = read();
    }
    for(int i = 1;i <= q; ++i) {
        e[i + p].tag = 1;
        e[i + p].u = read();
        e[i + p].v = read();
        e[i + p].w = read();
    }
    sort(e + 1,e + p + q + 1,cmp);
    for(int i = 1;i <= n; ++i) {
        F1.f[i] = i;
    }
    for(int i = 1;i <= m; ++i) F2.f[i] = i;
    for(int i = 1;i <= p + q; ++i) {
        if(e[i].tag == 0) {
            int x = F2.find(e[i].u);
            int y = F2.find(e[i].v);
            int z = e[i].w;
            if(x == y) {
                ans += z * n;
            }
            else {
                F2.merge(x,y);
                ans += z * cnt1;
                cnt2 ++;
            }
        }
        else {
            int x = F1.find(e[i].u);
            int y = F1.find(e[i].v);
            int z = e[i].w;
            if(x == y) {
                ans += z * m;
            }
            else {
                F1.merge(x,y);
                cnt1 ++;
                ans += z * cnt2;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}