poj2524(并查集水题)

题目链接http://poj.org/problem?id=2524

题目大意:学校共有n个同学,告诉你m对同学信仰同一宗教,问这个学校学生信仰宗教的数目最多为多少。

例:

Sample Input

10 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
10 4
2 3
4 5
4 8
5 8
0 0

Sample Output

Case 1: 1
Case 2: 7

解题思路:直接套并查集的板子就可以了,初始化n个集合默认他们都信任不一样的宗教,初始就用n个宗教,每次给你的两个同学那个号码将他们并到一个集合就可以了,最后统计时,每当有一对同学并了,答案减1就可以了。

附上代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int ans,n,m;
 6 int par[50005],rank[50005];
 7 
 8 void init(int x)
 9 {
10     for(int i=1;i<=x;i++)
11     {
12         par[i]=i;
13         rank[i]=0;
14     }
15 }
16 
17 int find(int x)
18 {
19     if(par[x]==x)
20         return x;
21     else
22         return par[x]=find(par[x]);
23 }
24 
25 void unite(int x,int y)
26 {
27     int fx=find(x);
28     int fy=find(y);
29     if(fx==fy) return;
30     if(rank[fx]>rank[fy])
31         par[fy]=fx;
32     else
33     {
34         par[fx]=fy;
35         if(rank[fx]==rank[fy])
36             rank[fx]++;
37     }
38 }
39 
40 bool same(int x,int y)
41 {
42     return find(x)==find(y);
43 }
44 
45 int main()
46 {
47     int kase=1;
48     while(cin>>n>>m&&(n||m))
49     {
50         init(n);
51         ans=n;
52         for(int i=0;i<m;i++)
53         {
54             int a,b;
55             cin>>a>>b;
56             unite(a,b);
57         }
58         for(int i=1;i<=n;i++)
59         {
60             if(par[i]!=i)
61                 ans--;
62         }
63         printf("Case %d: %d\n",kase++,ans);
64     }
65     return 0;
66 }

猜你喜欢

转载自www.cnblogs.com/zjl192628928/p/9438043.html