找老乡——并查集

认老乡

大学的同学来自全国各地,对于远离家乡步入陌生大学校园的大一新生来说,碰到老乡是多么激动的一件事,于是大家都热衷于问身边的同学是否与自己同乡,来自新疆的小赛尤其热衷。但是大家都不告诉小赛他们来自哪里,只是说与谁同乡,从所给的信息中,你能告诉小赛有多少人确定是她的同乡吗?

输入

每个测试实例首先包括2个整数,N(1 <= N <= 1000),M(0 <= M <= N*(N-1)/2),代表现有N个人(用1~N编号)和M组关系;

在接下来的M行里,每行包括2个整数,a,b,代表a跟b是同乡;

当N = 0,M = 0输入结束;

已知1表示小赛本人。

样例输入
3 1
2 3
5 4
1 2
3 4
2 5
3 2
0 0

输出
对于每个测试实例,输出一个整数,代表确定是小赛同乡的人数。

样例输出
0
4
时间限制
C/C++语言:1000MS其它语言:3000MS
内存限制
C/C++语言:65536KB其它语言:589824KB

 1 #include <stdio.h>
 2 #include <string.h>
 3 int  pre[1050];
 4 int t[1050];
 5 
 6 int Find(int x)
 7 {
 8     int r=x;
 9     while(r!=pre[r])
10         r=pre[r];
11 
12     int i=x,j;
13     while(pre[i]!=r)
14     {
15         j=pre[i];
16         pre[i]=r;
17         i=j;
18     }
19     return r;
20 }
21 
22 void mix(int x,int y)
23 {
24     int fx=Find(x),fy=Find(y);
25     if(fx!=fy)
26     {
27         pre[fy]=fx;
28     }
29 }
30 
31 int main()
32 {
33     int total = 0;
34     int N,M;
35     int Sum = 0;
36     int a,b;
37     int i = 0,j = 0,k = 0;
38     while(scanf("%d %d",&N,&M)&&N)//当有输入,且人数部位0是
39     {
40         total++;
41         for(i=1;i<=N;i++)//初始化
42         {
43             pre[i] = i;
44         }
45         for(j=1;j<=M;j++)//读入数据进行合并
46         {
47             scanf("%d %d",&a,&b);
48             mix(a,b);
49         }
50         int temp = pre[1];//第一个节点的老大
51         for(int s = 1;s<=N;s++)
52         {
53             Find(s);
54         }
55         for(k = 2;k<=N;k++)
56         {
57             if(pre[k] == temp)
58                 Sum ++;
59         }
60         t[total] = Sum;
61     }
62     //将结果存起来,存到t[1050]里
63     for(int y=1;y<=total;y++)
64     {
65         printf("%d",t[y]);
66         if(y!=total)
67         {
68             printf("
");
69         }
70     }
71 
72     return 0;
73 }

 

本小白新学习了并查集,资料分享如下:

http://blog.csdn.net/dellaserss/article/details/7724401/

觉得很不错吖~~

原文地址:https://www.cnblogs.com/yxh-amysear/p/7285753.html