hrbustoj 1073:病毒(并查集,入门题)

病毒
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 719(185 users) Total Accepted: 247(163 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号小朋友的根节点,依次与剩下所有的小朋友的根节点比较,相等则计数+1,表示这是和0号小朋友有关系的,即被感染的人。最后输出总计数(即被0号小朋友感染的人数)。

  套模板很容易过。

  代码:

 1 #include <stdio.h>

 2 

 3 /* 并查集模板  4 */

 5 int UFS_NUM;    //并查集中元素总数

 6 typedef struct node{  7     int data;    //节点对应的编号 

 8     int rank;    //节点对应秩 

 9     int parent;    //节点对应的双亲下标 

10 }UFSTree;        //并查集树的节点类型 

11 void MAKE_SET(UFSTree t[])    //初始化并查集树 

12 { 13     int i; 14     for(i=0;i<UFS_NUM;i++){ 15         t[i].data = i;        //数据为该点编号 

16         t[i].rank = 0;        //秩初始化为0 

17         t[i].parent = i;    //双亲初始化为指向自己 

18  } 19 } 20 int FIND_SET(UFSTree t[],int x)    //在x所在的子树中查找集合编号

21 { 22     if(t[x].parent == x)    //双亲是自己 

23         return x;    //双亲是自己,返回 x 

24     else    //双亲不是自己 

25         return FIND_SET(t,t[x].parent);    //递归在双亲中查找x 

26 } 27 void UNION(UFSTree t[],int x,int y)    //将x和y所在的子树合并

28 { 29     x = FIND_SET(t,x);    //查找 x 所在分离集合树的编号 

30     y = FIND_SET(t,y);    //查找 y 所在分离集合树的编号 

31     if(t[x].rank > t[y].rank)    //y 节点的秩小于 x节点的秩 

32         t[y].parent = x;        //将 y 连接到 x 节点上,x 作为 y 的双亲节点 

33     else{                //y 节点的秩大于等于 x 节点的秩 

34         t[x].parent = y;            //将 x 连接到 y 节点上,y 作为 x 的双亲节点 

35         if(t[x].rank==t[y].rank)    //x 和 y的双亲节点秩相同 

36             t[y].rank++;            //y 节点的秩增 1 

37  } 38 } 39 int main() 40 { 41     int i,n,m,x,y; 42     while(scanf("%d%d",&n,&m)!=EOF){ 43         UFSTree t[50005]; 44         UFS_NUM = n; 45  MAKE_SET(t); 46         for(i=1;i<=m;i++){ 47             scanf("%d%d",&x,&y); 48  UNION(t,x,y); 49  } 50         int f0 = FIND_SET(t,0); 51         int sum=0; 52         for(i=0;i<n;i++) 53             if(FIND_SET(t,i)==f0) 54                 sum++; 55         printf("%d\n",sum); 56  } 57     return 0; 58 }

 

Freecode : www.cnblogs.com/yym2013

你可能感兴趣的:(并查集)