病毒 | ||||||
| ||||||
Description | ||||||
某种病毒袭击了某地区,该地区有N(1≤N≤50000)人,分别编号为0,1,...,N-1,现在0号已被确诊,所有0的直接朋友和间接朋友都要被隔离。例如:0与1是直接朋友,1与2是直接朋友,则0、2就是间接朋友,那么0、1、2都须被隔离。现在,已查明有M(1≤M≤10000)个直接朋友关系。如:0,2就表示0,2是直接朋友关系。 | ||||||
Input | ||||||
第一行包含两个正整数N(1≤N≤50000),M(1≤M≤100000),分别表示人数和接触关系数量; | ||||||
Output | ||||||
输出数据仅包含一个整数,为共需隔离的人数(包含0号在内)。 | ||||||
Sample Input | ||||||
100 4 | ||||||
Sample Output | ||||||
3 |
简单并查集。
代码如下:
#include <stdio.h>
int a[50011];
int find(int x)
{
int r=x;
while (r!=a[r])
r=a[r];
int j=x;
int t;
while (a[j]!=r) //路径压缩(此题需要这个步骤,根据代码自己理解理解吧,不需要死记)
{
t=a[j];
a[j]=r;
j=t;
}
return r;
}
void join(int x,int y)
{
int fx,fy;
fx=find(x);
fy=find(y);
if (fx!=fy)
a[fx]=fy;
}
int main()
{
int n,m; //学生数、团体数
int tn; //每个团体的人数
int t;
int t1,t2;
int ans;
int root;
scanf ("%d %d",&n,&m);
//首先初始化
for (int i=0;i<n;i++)
{
a[i]=i;
}
for (int i=1;i<=m;i++)
{
scanf ("%d%d",&t1,&t2);
join(t1,t2);
}
root=find(a[0]); //0的根
ans=0;
for (int i=0;i<n;i++)
{
if (find(a[i])==root)
ans++;
}
printf ("%d\n",ans);
return 0;
}