图论入门-并查集

More is better

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 327680/102400 K (Java/Others)
Total Submission(s): 33215    Accepted Submission(s): 11744


Problem Description
Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.

Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
 

Input
The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
 

Output
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
 

Sample Input
4 1 2 3 4 5 6 1 6 4 1 2 3 4 5 6 7 8
 

Sample Output
4 2
 
 
Hint
A and B are friends(direct or indirect), B and C are friends(direct or indirect), then A and C are also friends(indirect). In the first sample {1,2,5,6} is the result. In the second sample {1,2},{3,4},{5,6},{7,8} are four kinds of answers.
 
题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=1856

  这个题是个很简单的并查集的题, 关于并查集的博客有很多, 我这里就只放代码, 讲一下操作, 原理的话, 如果有兴趣可以去查一下。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<iomanip>
 4 #include<queue>
 5 #include<map>
 6 #include<set>
 7 #include<stack>
 8 #include<list>
 9 #include<algorithm>
10 #include<cmath>
11 #include<cstring>
12 #include<string>
13 #include<sstream>
14 #include<fstream>
15 #define go(t) int t;    cin>>t;     while(t--)
16 #define ll long long
17 #define rep(i, a, n) for(int i = a; i < n; i++)
18 #define res(i, a, n) for(int i = a - 1; i >= n; i--)
19 using namespace std;
20 const int inf = -1;
21 const int mod = 1e9 + 7;
22 const double pi = acos(-1);
23 const int N = 10000020;
24 
25 //fa表示父节点, val表示节点的权值
26 int fa[N], val[N], n, x, y;
27 
28 //先初始化, fa一开始指向自身, val一开始都为1, 因为一开始只有自己
29 //还有就是, init写了记得要用, 我本身老师写了但是忘了用
30 void init(){
31     rep(i, 1, N + 1){
32         fa[i] = i;
33         val[i] = 1;
34     }
35 }
36 
37 //查找父节点, 注意fa[x] = Find(fa[x]), 前面一定要加fa[x] = , 路径压缩一下, 不然会超时
38 //路径压缩会把多级结构压缩成一级, 避免了每次查找过程中不必要的耗时
39 //建议画图理解
40 int Find(int x){
41     return x == fa[x] ? x : fa[x] = Find(fa[x]);
42 }
43 
44 //联合节点, 可以把这个理解成为树, 如果两个节点不在同一颗树上, 就把两个节点各自所在的树联合
45 //只把根节点联合就可以了
46 int Unite(int x, int y){
47     x = Find(x);    y = Find(y);
48     if(x != y){             //如果两个节点不在同一颗树上
49         fa[x] = y;          //联合两棵树
50         val[y] += val[x];   //权值相加
51     }
52     return max(val[x], val[y]);
53 }
54 
55 int main(){
56     while(cin >> n){
57         init();
58         int ans = 1;
59         rep(i, 1, n + 1){       //这个在我的宏定义里面
60             scanf("%d%d", &x, &y);      //这个由于数据量比较大, 不要用cin, 浪费时间
61             ans = max(ans, Unite(x, y));
62         }
63         cout << ans << endl;
64     }
65     return 0;
66 }
View Code

猜你喜欢

转载自www.cnblogs.com/123zhh-helloworld/p/9100262.html