HDU 1856 More is better (并查集)

题意:

  给你两个数代表这两个人是朋友,朋友的朋友还是朋友~~,问这些人组成的集合里面人最多的是多少。。。

思路:

  属于并查集了,我用的是带路径压缩的,一个集合里面所有元素(除了根节点)的父节点都是根节点,最后统计下哪个根节点出现的次数最多就OK了~~

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <cctype>
 7 #include <algorithm>
 8 using namespace std;
 9 const int MAXN = 1e5 + 3;
10 int pre[MAXN];          //存放父节点的数组
11 int cnt[10000000+3]={0};  //利用下标代表根节点,值代表出现的次数~
12 int Find(int x)
13 {
14     int r = x;
15     while(pre[r] != r)
16     {
17         r = pre[r];
18     }
19     int i = x,j;
20     while(pre[i] != r)
21     {
22         j = i;
23         i = pre[i];
24         pre[j] = r;
25     }
26     return r;
27 }
28 
29 void Mix(int a,int b)
30 {
31     int x = Find(a);
32     int y = Find(b);
33     if(x > y)
34     {
35         pre[x] = y;
36     }
37     if(x < y)
38     {
39         pre[y] = x;
40     }
41 }
42 
43 int mycmp(int a, int b)
44 {
45     return a > b;
46 }
47 
48 void Mst()
49 {
50     for(int i = 1; i <= MAXN; i++)
51     {
52         pre[i] = i;
53     }
54 }
55 int main()
56 {
57     int N;
58     while(~scanf("%d",&N))
59     {
60         Mst();
61         memset(cnt,0,sizeof(cnt));
62         while(N--)
63         {
64             int boyf,boys;
65             scanf("%d%d",&boyf,&boys);
66             Mix(boyf,boys);
67         }
68         for(int i = 1;i <= MAXN;i++){
69             Find(i);                  //最后要路径压缩,使得所有的节点都指向根节点。。
70             cnt[pre[i]] ++;          //用来存放根节点出现的次数的数组         
71         }
72         int ans = 0;
73         for(int i = 1;i <= MAXN;i++){//找出最大的
74             if(cnt[i] > ans)
75                 ans = cnt[i];
76         }
77         cout << ans <<endl;
78     }
79     return 0;
80 }
It's not numeral,character and punctuation .It's my life.
原文地址:https://www.cnblogs.com/Ash-ly/p/5397655.html