您的位置:首页 > 其它

poj3723 最大权森林

2014-06-12 01:55 267 查看
3723

题目大意:自己看

分析:最后答案就是10000*(n+m)-所有人加进来能获得的最大权值和,把权值取负就是求最小生成树了,节点编号是从0开始的- -

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#include <map>
#include <queue>
#include<vector>
#define maxn 20010
#define maxm 50010
#define INF 0x3fffffff
using namespace std;
struct edge{
int u,v,cost;
edge(){}
edge(int _u,int _v,int _cost){
u=_u;v=_v;cost=_cost;
}
};
bool cmp(edge a,edge b){
return a.cost<b.cost;
}
int V,E;
int father[maxn];
void init(){
for(int i=0;i<=V;++i){
father[i]=i;
}
}
int Find(int x){
return father[x]==x?x:father[x]=Find(father[x]);
}
void Union(int x,int y){
x = Find(x);
y = Find(y);
if(x!=y)father[x]=y;
}
bool same(int x,int y){
return Find(x)==Find(y);
}
edge G[maxm];
int cnt=0;
void addedge(int u,int v,int cost){
G[cnt++]=edge(u,v,cost);
}
int kruskal(){
sort(G,G+cnt,cmp);
init();
int ans=0;
for(int i=0;i<cnt;++i){
edge e = G[i];
if(!same(e.u,e.v)){
Union(e.u,e.v);
ans+=e.cost;
}
}
return ans;
}
int n,m,R;
int main (){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&R);
cnt=0;
V=n+m;
for(int i=0;i<R;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v+n,-w);
}
printf("%d\n",(n+m)*10000+kruskal());
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: