POJ 3723 - Conscription

运用kruskal算法的最大生成树的基础题,直接1A。

具体请参考:http://www.cnblogs.com/liangrx06/p/5083763.html

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,r;
struct Node{
	int x,y,d;
}node[50000+5];
int par[20000+5];
bool cmp(Node x,Node y){return x.d>y.d;}
void init()
{
	sort(node+1,node+r+1,cmp);//按d从大到小排列,以满足最大生成树的要求
	for(int i=1;i<=n+m;i++) par[i]=i;//初始化并查集
}
int find(int x){return( par[x]==x ? x : par[x]=find(par[x]) );}
int kruskal()
{
	int d_sum=0;
	for(int i=1;i<=r;i++)
	{
		int x=find(node[i].x),y=find(node[i].y);
		if(x != y)//找到一条属于最大生成树的新边
		{
			par[y]=x;//合并
			d_sum+=node[i].d;//这条边属于最大生成树,即对应的题目中要使用的“关系”( ‵▽′)ψ
		}
	}
	return d_sum;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("\n\n%d%d%d",&n,&m,&r);// n个girl , m个boy , r句话 
		for(int i=1;i<=r;i++)
		{
			int x,y,d;
			scanf("\n%d%d%d",&x,&y,&d); //girl - x ; boy - y 
			node[i].x=x+1,node[i].y=n+1+y;//这样可以确保男女孩的编号必然是不同的
			node[i].d=d;
		}
		init();
		int d_sum=kruskal();
		printf("%d\n",(n+m)*10000 - d_sum);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值