您的位置:首页 > 其它

Hust oj 1073 病毒(并查集)

2016-03-14 18:03 337 查看
病毒
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 1816(467 users)Total Accepted: 632(409 users)Rating:



Special Judge: No
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),分别表示人数和接触关系数量;

在接下来的M行中,每行表示一次接触,;

每行包括两个整数U, V(0 <= U, V < N)表示一个直接朋友关系。

Output
输出数据仅包含一个整数,为共需隔离的人数(包含0号在内)。

Sample Input
100 4

0 1

1 2

3 4

4 5

Sample Output
3

一道水的不行的并查集。。只要查找与0相同的上级就可以了

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;

int pre[100005];
int find (int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}

void join(int x,int y)
{
int fx=find (x),fy=find (y);
if(x!=y)
pre[fx]=fy;
}

int main()
{
int n,m;
int i,j,k;
int a,b;
while(~scanf("%d%d",&n,&m))
{
int cnt=0;
for(i=0;i<n;i++)
{
pre[i]=i;
}
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
join(a,b);
}
for(i=0;i<n;i++)
{
if(find (0)==find(i))
{
cnt++;
}
}
printf("%d\n",cnt);
}

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: