朋友圈
描述
有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
这一题需要用到并查集,其实就是两个人中小的跟着大的走,就是赋值,先假设每个人都最大,然后再来一个一个比较,就题目中数据而言,开始是1 2 3 4 5,来个1 2后,1跟2走,变成2 2 3 4 5,然后来个2 3,2跟3走,2 3 3 4 5,然后来个4 和5,4跟5走,变成2 2 3 5 5,然后再来个看那个人的数字没变,没变就说明他带了一个队伍(这里也可以大的跟着小的走)
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
long long a[110000]={0};
long long ask(long long a[],long long per)
{
long long pos=per;
while(a[per]!=per) //如果值不一样,说明这个人跟别人走了,就去找他跟谁走了,直到找到
per=a[per];
a[pos]=per; //找到了就说明一下,说明这个人跟谁跑了
return per; //返回带头那个人
}
main()
{
long long x,y,t1,t2,n,m,sta,end,count;
while(scanf("%lld %lld",&m,&n)!=EOF)
{
for(x=1;x<=m;x++)
a[x]=x; //先假设每个人都带着自己,没跟人跑
for(x=0;x<n;x++)
{
scanf("%lld %lld",&sta,&end);
t1=ask(a,sta);
t2=ask(a,end);
if(t1!=t2) //如果带头的不一样,那么小的跟着大的走,也可以大的跟着小的走
a[t1]=t2;
}
count=0;
for(x=1;x<=m;x++)
if(a[x]==x) count++; //然后找从始至终自己带头的人,那么这就是一个队伍
printf("%lld\n",count);
}
return 0;
}