标签:highlight abc 相对 节点 main 初始化 mic class 自己
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。
举一个例子
假设有A B C D E五个人
A ,D两人感冒了。
A和B玩传染给了 B ,B和C玩传染给了C
D和E玩传染到了 E

E只和D接触过,所以D E是一种同类型感冒。
B和A接触染了感冒,C和B接触有了感冒,所以A B C 是一种同类型感冒。
但一个个病友形成圈子后感染源头是谁,谁感染的感冒都不要紧,关键问题是根据不同的感冒类型治病,ABC一种,DE一种。
开始并查集的三步走 初始化 查找 合并。
1.初始化
定义一个数组对该数组每个值赋值其本身
2.查找
找到是谁感染的病,最后形成一个或多个病友圈,每个病友圈都有相对应的治疗方法对症下药,也就是找到根节点。
核心代码
1 rott(long long int rs) 2 { 3 long long int i,j; 4 i=rs; 5 while(rs!=pre[rs])//找病原体 6 rs=pre[rs]; 7 8 return pre[rs];//返回老大 9 }
3.合并
一般输入的两个数一起玩的就会互相感染,所以把他们两个合并起来看看是否有病友圈。
long long int s1,e1;//一个圈的人
scanf("%lld%lld",&s1,&e1);
long long int r1=rott(s1); //找他是否被感染
long long int r2=rott(e1); //同理
if(r1!=r2)
{
pre[r1]=r2; //找根节点
mp--; //独立的个体少一
}
最后完整代码
#include<stdio.h>
long long pre[2000000]; //里面的老哥个个都是人才
rott(long long int rs)
{
long long int i,j;
i=rs;
while(rs!=pre[rs])//找上级
rs=pre[rs];
while(i!=rs)
{
j=pre[i];
pre[i]=rs;
i=j;
}
return pre[rs];//返回老大
}
int main()
{
long long int n,m;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
long long int i,j;
long long int mp=n;
for(i=1;i<=n;i++)
pre[i]=i; //每个人都是自己生活的主宰
while(m--) //分久必合合久必分
{
long long int s1,e1;//一个圈的人
scanf("%lld%lld",&s1,&e1);
long long int r1=rott(s1);
long long int r2=rott(e1);
if(r1!=r2)
{
pre[r1]=r2;
mp--; //独立的个体少一
}
}
printf("%lld\n",mp);
}
}
标签:highlight abc 相对 节点 main 初始化 mic class 自己
原文地址:https://www.cnblogs.com/johnfllora/p/12231031.html