简单题,列出最大集合所含元素个数即可。要用带路径压缩的并查集,不然会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;
}