自己的理解
这个算法呢,可以用于查找强盗同伙,查找一堆人里的朋友圈,简单说,就是由一些直接的信息(每两个人的联系)来推出党派(也就是根节点)个数。通过其他博主和《啊哈!算法》中的讲解,自己理解了一下并查集的内容,感觉,这是个超级有趣超级简单容易理解的算法知识。
例题
-下面通过一个题目详细说明一下:
有n个人,编号1-n。现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。即: 如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。现在,给出m个关系,每个关系描述:a b 表示 编号为a和编号为b的人是朋友关系。
最后问,会有多少个朋友圈。
具体步骤 模板
- 第一步,我们将这n个人放进数组里,并初始化
- 第二步,找朋友,即看哪些人属于同一朋友圈(找到同一个大BOSS)
用到了一个算法,叫路径压缩,增大了查找的效率,代码较为简单,用到了递归的知识,代码如下:
int get(int root)//找大BOSS(同一个根节点)
{
if(c[root]==root)//表示已找到
return root;
else
{
c[root]=get(c[root]);//递归,直到找到为止
return c[root];
}
}
- 第三步,合并朋友圈,看哪些人是同一朋友圈(有着同一个大BOSS根节点),代码如下:
void join(int a,int b)
{
int t1,t2;//分别为两人的大BOSS(根节点)
t1=get(a);
t2=get(b);
if(t1!=t2)//判断这两个大BOSS是否在同一朋友圈
{
c[t2]=t1;
}
return;
}
- 最后一步,查找最终的朋友圈个数(大BOSS个数)
完整代码
#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))
{
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;
}