hdu 1856 More is better (究级版)

简单题,列出最大集合所含元素个数即可。要用带路径压缩的并查集,不然会TLE。另外,要注意当n为0时,要输出1. 题目有说: or there is only one boy left. 可能有100000个男孩,但都没配对,答案是1。


AC代码:

#include<iostream>
using namespace std;
#define NUM 10000005
int set[NUM];
int ans[NUM];//以i为顶点的集合所含元素个数
void init()
{
	for(int i=0;i<NUM;i++){
		set[i]=i;
		ans[i]=1;
	}
}

int find(int x)//朴素版的查找
{
	int r;
	r=x;
	while(set[r]!=r)
		r=set[r];
	return r;
}

int find1(int x)//带路径压缩的查找(递归版)
{
	if(x!=set[x]){
		set[x]=find1(set[x]);
	}
	return set[x];
}

int find2(int x)//带路径压缩的查找(非递归版)
{
	int k, j, r;
    r = x;
    while(r != set[r])     //查找根节点
        r = set[r];      //找到根节点,用r记录下
    k = x;  
	while(k != r)             //非递归路径压缩操作
    {        
			j = set[k];         //用j暂存set[k]的父节点
			set[k] = r;        //set[x]指向根节点 
			k = j;                    //k移到父节点   
	}  
	return r;         //返回根节点的值
}

void merge(int a, int b)
{
	int x=find2(a);
	int y=find2(b);
	if(x!=y){
		set[y]=x;
		ans[x]+=ans[y];
	}
	
}

int main()
{
	int n,a,b,i,iMax;
	//freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
	while(cin>>n&&n>=0){
		init();
		iMax=-1;
		for(i=0;i<n;i++){
			cin>>a>>b;
			merge(a,b);
		}
		for(i=1;i<NUM;i++){
			if(set[i]==i&&iMax<ans[i])
				iMax=ans[i];
		}
		cout<<iMax<<endl;

	}

	return 0;
}



你可能感兴趣的:(hdu 1856 More is better (究级版))