并查集
Posted johnfllora
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集相关的知识,希望对你有一定的参考价值。
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。
举一个例子
假设有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 ",mp); } }
以上是关于并查集的主要内容,如果未能解决你的问题,请参考以下文章