查并集的分析
查并集通过一个一维数组来实现,其本质是维护一个团队,刚开始的时候,每一个人都是孤立的,之后通过一些有条件,将这些个人合并为一个团队,在合并的过程中就是找朋友,遵循靠左的原则和找到团队领袖,来确定是否为一个团队的人·。
查并集的应用
让我们通过举例子的方式来更好地理解查并集吧
有n个人,编号1-n。
现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。
即: 如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。
现在,给出m个关系
每个关系描述:
a b
表示 编号为a和编号为b的人是朋友关系。
格式
输入格式
输入n和m
接下来m行,每行为a b
输出格式
最后问,会有多少个朋友圈。
这就是一个明显的查并集问题
思想是使用数组,初始化令数组的下标与该数的值相同,根据靠左原则进行改变,最后若下标还是与该书的值一样,就代表为一个团队的领袖,通过确定团队领袖的个数来确定有多少个团队。
下面通过代码更好的理解吧(养成从主函数开始看代码的好习惯哦)
#include<stdio.h>
int a[1000000]={0},sum,n,m,k,sun=0;
void start()//让数组初始化的函数
{
int i;
for(i=1;i<=n;i++)
a[i]=i;
}
int chang(int v)
{
if(a[v]==v)//如果数组下标等于该值,则代表该数为领袖
return v;
else
{
a[v]=chang(a[v]);//递归,直至找到该数的领袖
return a[v];
}
}
void ban(int p,int q)
{
int t1,t2;
t1=chang(p);//分别找到这俩个数的领袖
t2=chang(q);
if(t1!=t2)//如果俩人领袖不一样,靠左原则,让左边的人当团队的新领袖
{
a[t2]=t1;
}
}
int main()
{
int i,x,y;
scanf("%d%d",&n,&m);
start();
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
ban(x,y);
}
for(i=1;i<=n;i++)
if(a[i]==i)//若下标等于该数值,则确定为一个领袖
sum++;
printf("%d\n",sum);
return 0;
}