题目链接:HDU1856
题目大意:求节点最多的那个连通分量,输出节点数量。
AC代码:
/*
2017年8月28日13:57:13
HDU1856
并查集入门
AC
*/
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
const int maxn=1e7;
int pre[maxn];
int num[maxn];
int n,ans;
int find(int x){
int r=x;
while(pre[r]!=r) r=pre[r];//查找到根节点为止
int i=x,j;
while(i!=r){
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy) pre[fx]=fy;
//else circle=true; 判断环
}
void init(int n){
ans=0;
for(int i=1;i<=maxn;i++){
pre[i]=i;
num[i]=0;
}
for(int i=1;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
join(a,b);
}
}
void solve(){
//关键代码 把每个点的父亲全部更新为祖先
for(int i=1;i<=maxn;i++){
if(find(i)!=i){
int p=find(i);
while(p!=find(p)) p=find(p);
pre[i]=p;
}
}
// for(int i=1;i<=8;i++) printf("pre[%d]=%d\n",i,pre[i]);
//然后扫一遍,每个祖先出现次数,记录次数最多的那个即可
for(int i=1;i<=maxn;i++){
num[pre[i]]++;
if(num[pre[i]]>ans) ans=num[pre[i]];
}
printf("%d\n",ans);
}
int main(){
int n;
while(~scanf("%d",&n)){
init(n);
solve();
}
return 0;
}