【HZNU Summer training】HDU1856 More is Better (并查集最大集合)

    此题的题意是,在一个房间里有一堆邻家♂boy,他们互相之间存在着一些py♂关系,你需要找出他们中间最大的一个朋友圈(朋友关系具有传递性),并输出这个朋友圈中的人数。

    看到朋友关系很难不想到并查集,但此题要求输出最大集合的元素个数,那么就必须做一些处理。起初我打算处理完输入后再做一遍遍历,找出每个集合的元素个数,最后找出最大值(场面过于暴力)。后来想起这道题数据规模有1e7,暴力个蛇皮自行车。遂想到在并查集处理数据的过程中把集合元素个数也顺便处理。

    先上代码:

#include<iostream>
#include<cmath>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;
int fa[10000005];
int sum[10000005];
int maxsum=1;
int find(int a) {
	return a==fa[a]?a:fa[a]=find(fa[a]);
}
void mix(int x,int y) {
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy) {
		fa[fx]=fy;
		sum[fy]+=sum[fx];
		maxsum=max(maxsum,sum[fy]);
	}
}
void init(){
	for(int i=1;i<=10000000;i++){
		fa[i]=i;
		sum[i]=1;
	}
}
int main() {
	int n;
	while(cin>>n){
		maxsum=1;
		init();
		int a,b;
		for(int i=0;i<n;i++){
			cin>>a>>b;
			mix(a,b);
		}
		cout<<maxsum<<endl;
	}
	return 0;
}

   可以看到整体框架与一般的并查集裸题差不多,但多了一个sum数组,并且在mix函数中做了一些改动:

int sum[10000005];
int maxsum=1;
void mix(int x,int y) {
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy) {
		fa[fx]=fy;
		sum[fy]+=sum[fx];             //元素个数处理
		maxsum=max(maxsum,sum[fy]);   //维护最大集合元素值
	}
}
void init(){
	for(int i=1;i<=10000000;i++){
		fa[i]=i;
		sum[i]=1;
	}
}

    sum数组用来存集合元素数,如何存?看下面的mix函数。

    我们知道并查集是一个树形数据结构,根节点即是find函数最终返回的节点,同时也可用它来表示整个集合。而普通的并查集中,在mix函数里,只需将两元素的根节点建立联系(即代码走不加注释的部分),这个过程相当于把一棵树的根嫁接到另一棵树的根上。现在我们知道,我们手里的这棵树(并查集)是具有一些属性的,比如元素个数,那我在嫁接的时候,顺便将这个值加到受体上,就可以完成处理,正如代码中带注释部分所示。这里需要注意的是,要找准双方的根节点,不要接反了。

    要注意的是,sum数组需要初始化为1,因为每个集合都带有它本身,元素个数是1起步的,昨天脑子抽风,memset了一套0,智力孤危。

    骚的是交题的时候,同样的代码交G++会TLE,交C++就AC,长见识了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值