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

posted @ 2014-04-26 17:40  Freecode#  阅读(597)  评论(0编辑  收藏  举报