6个朋友(CODEVS 2832)

题目链接

##考查并查集##

#include<iostream>
#include<algorithm>
using namespace std;
int f[100005]={0},n,m,sum,maxPeople=0; 
int tcount[100005]={0};
//初始化,数组里面存的是自己的数组下标的编号就好了 
void init(){
	for(int i=1;i<=n;i++){
		f[i]=i;
	}
}
//找祖宗的递归函数
int getf(int v){
	if(f[v]==v){
		return v;
	}else{
		//找到祖宗后,顺带路径压缩 
		f[v]=getf(f[v]);
		return f[v];
	}
} 
//合并两子集合的函数
void merge(int v,int u){
	int t1,t2;
	t1=getf(v); 
	t2=getf(u);
	if(t1!=t2){
		f[t2]=t1; 
	}
} 
//用于后面排序 
bool compare(int a,int b)
{
  return a>b; 
}
//主函数开始
int main(){
	int x,y;
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		merge(x,y);
	}
	for(int i=1;i<=n;i++){
		if(f[i]==i){
			sum++;
		}
	}
	if(sum<=6){
		cout<<"^_^";
	}else{
		//之前路径压缩可能完成了一大半,为了确保压缩完成,这里进行一次完整的压缩路径 
		for(int i=1;i<=n;i++){
			int temp=getf(f[i]);
			tcount[temp]++;
		}	
		//从大到小排序 
		sort(tcount+1,tcount+n+1,compare);
 
		//前面6个相加 
		for(int i=1;i<=6;i++){
			maxPeople+=tcount[i];
		} 
		cout<<"T_T"<<endl<<maxPeople;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_37418246/article/details/82682064
今日推荐