并查集
并查集是一种树型的数据结构,用于处理一些不交集的合并及查询问题。
例题
描述 有n个人,编号1-n。 现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。 即:
如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。
现在,给出m个关系 每个关系描述: a b 表示编号为a和编号为b的人是朋友关系。
输入格式
输入 n和m 接下来m行,每行为a b
输出格式
最后问,会有多少个朋友圈。
样例输入 Copy
5 3
1 2
2 3
4 5
样例输出 Copy
2
首先我们让一个人都有一个欣赏的人;
朋友圈都有一个核心人物,来代表这个朋友圈;
朋友圈内的所有人都直接或间接欣赏这个核心人物;
x [ i ] = m 代表 i 这个人欣赏的人是 m;
如果i=m那么i就是这个朋友圈的核心人物;
#include <stdio.h>
int x[100000];
int find( int a)
{
int son,tmp;
son=a;
while(a!= x[a])
a=x[a];//寻找这个人所在朋友圈的核心人物;
while(x[son]!=a)
{
tmp=x[son];
x[son]=a;
son=tmp;
}//将路径压缩,比如a欣赏b;b欣赏c;c欣赏d;d欣赏自己;d 就是核心人物;我们让a,b,c,d都直接欣赏d,这样就不用一个一个的找核心人物了;
return a;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,pyq=0;
for(i=1;i<=n;i++)
{
x[i]=i;//没有朋友认识时,自己就是核心人物;
}
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
{
x[find(a)]=find(b);//让a 的核心人物和b 一样,这样朋友圈就合并了;
}
}
//这时我们只需要找有多少核心人物,就知道有几个朋友圈了;
for(i=1;i<=n;i++)
if(x[i]==i)
pyq++;//如果i是核心人物,那么朋友圈的个数就加一
printf("%d\n",pyq);
}
return 0;
}