@TOC
五一去重庆也回来了,说实话也该收收心开始学习了,马上一堆考试就要来了,想想就挺头大的。今天刚刚赶路回来,就写写简单的吧,过后一阵估计写博客也慢下来了,一是还是以学业为重,二是也不太想每天记挂博客这件事。
话不多说,今天学并查集。
并查集就是简单说,由一些直接的信息(每两个人的联系)来推出团伙(也就是根节点)个数。
例
有n个人,编号1-n。现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。即: 如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。现在,给出m个关系,每个关系描述:a b 表示 编号为a和编号为b的人是朋友关系。
最后问,会有多少个朋友圈。
#include<stdio.h>
int c[100005]={0};
int get(int root)//找同一个根节点
{
if(c[root]==root)//表示已找到
return root;
else
{
c[root]=get(c[root]);//递归,直到找到为止
return c[root];
}
}
void join(int a,int b)
{
int t1,t2;//分别为两人的根节点
t1=get(a);
t2=get(b);
if(t1!=t2)//判断这两个根节点是否在同一朋友圈
{
c[t2]=t1;
}
return;
}
int main()
{
int n,m,i,a,b,sum;
while(~scanf("%d%d",&n,&m))//n为人数,m为关系
{
sum=0;
for(i=1;i<=n;i++)//初始化关系,每个人都只认识自己
c[i]=i;
while(m--)
{
scanf("%d%d",&a,&b);
join(a,b);//开始把人群分类
}
for(i=1;i<=n;i++)
{
if(c[i]==i)//找到根节点(领袖)(只认识自己的)
sum++;
}
printf("%d\n",sum);
}
return 0;
}
测试:
(5个人7个关系)