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;
}
原文地址:https://www.cnblogs.com/akoasm/p/10107612.html