其他分享
首页 > 其他分享> > 并查集

并查集

作者:互联网

心得:看那个博客的时候,感觉很生动很形象,一下子就看懂了,在写那个题目的时候,按照给的方法来做,有问题,仔细检查之后,发现那个路径压缩函数好像没有用到,于是我就把第一次调用过的函数再调用一次,这样就可以知道有几个掌门了,emmm,这个题目我觉得只要细心,应该还是没问题的。

原理:就是把一个人用a[i]中的i表示,假设每个人都有且只知道他的上级,如a[i]=t;上级或许还有上级,直到a[i]=i位置,就找到了上级是谁,然后两个人碰面,确定是不是友人,就看掌门是否一样,然后就一层一层往上问,最终确定是不是同一个掌门,路径压缩函数就是让每一个人都知道他们的掌门是谁,方便确定是不是盟友。

主要代码 

int unionsearch(int root) //查找根结点
{
int son, tmp;
son = root;
while(root != pre[root]) //我的上级不是掌门
root = pre[root];
while(son != root) //我就找他的上级,直到掌门出现
{
tmp = pre[son];
pre[son] = root;
son = tmp;
}
return root; //掌门驾到~~
}(找掌门的,红色段是路径压缩函数,不过一开始好像没有用到这个)

void join(int root1, int root2) (两个人碰面,看是不是盟友)
{
int x, y;
x = unionsearch(root1);
y = unionsearch(root2);
if(x != y) (发现不是)
pre[x] = y; //打一仗,谁赢就当对方老大
}

话不多说直接上题:

有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
(本人代码仅供参考)

#include<stdio.h>
long long int a[100000],b[100000]={0},t=0;
long long int chazhao(long long int root)
{
long long int son,tmp;
son=root;
while(root!=a[root])
{
root=a[root];
}
while(son != root)
{
tmp = a[son];
a[son] = root;
son = tmp;
}
return root;
}
int main()
{
long long int n,m,i,total,x,y,p,q;
scanf("%lld %lld",&n,&m);
total=n-1;
for(i=1;i<=n;i++)
a[i]=i;
for(i=0;i<m;i++)
{
scanf("%lld %lld",&q,&p);
x=chazhao(q);
y=chazhao(p);
if(x!=y)
{
a[y]=x;
total--;
}
}
for(i=1;i<=n;i++)
{
chazhao(i);
}
for(i=1;i<=n;i++)
{
b[a[i]]++;
}
for(i=1;i<=n;i++)
if(b[i]!=0)
t++;
printf("%lld",t);
return 0;
}(大概就这样,emmm,很好理解应该)

标签:tmp,int,查集,掌门,son,long,root
来源: https://www.cnblogs.com/cyz1593574682/p/12230283.html