地址 poj.org/problem?id=3723

最大生成树 更新一个板子

题意:征用所有人需要(n+m)*10000元。男孩与女孩之间有联系的,征兵所需费用 -d元

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;

const int maxn_e = 50000+5;
const int maxn_n = 20000+5;
const int maxn = 1e3+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI=acos(-1.0);

struct node{
	int u,v,dis;
    node(){};
    node(int a,int b,int c){u=a,v=b,dis=c;}
    bool operator<(const node &a) const {return dis > a.dis;}
}edge[maxn_e];

int pre[maxn_n];

void init(){for(int i=0;i<=maxn_n;i++) pre[i]=i;}
int finds(int x){return pre[x]!=x?pre[x]=finds(pre[x]):x;}
void unions(int x,int y){x=finds(x);y=finds(y);x!=y?pre[x]=y:1;}

int kruskal(int n){
	init(); 
	sort(edge,edge+n);
	node e;
	int res=0;
	for(int i=0;i<n;i++){
		e=edge[i];
		if(finds(e.u)!=finds(e.v)){
			unions(e.u,e.v);
			res+=e.dis;
		}
	}
	return res;
}

int main(){
	int t,q,wo,man,st,ed,dis;
	scanf("%d",&t);
	while(t--){
		scanf("%d %d %d",&man,&wo,&q);
		for(int i=0;i<q;i++){
			scanf("%d %d %d",&st,&ed,&dis);
			edge[i]=node(st,ed+man,dis);
		}
		int ans=(man+wo)*(1e4);
		printf("%d\n",ans-kruskal(q));
	}
	return 0; 
}