More is better--hdu1856(并查集)

More is better

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

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.

这个题的意思就是输入是好友的两人,两好友的盆友具有传递性!最后输出互相是好友最多的一群有多少人?

用并查集,具体来看注释部分!

 1 #include <iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 #define maxn 100000
 6 using namespace std;
 7 int ran[maxn],per[maxn],via[maxn],num[maxn],n,sum;
 8 void init()
 9 {
10     int i;
11     for(i=1;i<=maxn;i++)
12     {
13         per[i]=i;
14         num[i] = 1;//记录每个根节点所包含的子节点
15     }
16 }
17 int find(int x)//查找函数
18 {
19     int t=x;
20     while(t!=per[t])
21      t=per[t];
22      int i=x,j;
23      while(i!=t)
24      {
25          j=per[i];
26          per[i]=t;
27          i=j;//压缩路径
28      }
29      return t;
30 }
31 void join(int x,int y)//合并函数,合并图
32 {
33     int fx=find(x);
34     int fy=find(y);
35     if(fx!=fy)
36     {
37         per[fx] = fy;
38         num[fy] += num[fx];
39         sum = max(sum, num[fy]);//求出各个树中子节点最多的
40     }
41     else
42         return ;
43 }
44 int main ()
45 {
46     int a,b,i,w,n;
47     while(scanf("%d",&n)!=EOF)
48     {
49         if(n == 0){
50             printf("1\n");//特殊坑爹数据
51             continue;
52         }
53         init();
54         w=n;
55         sum = 0;
56         while(w--)
57         {
58             scanf("%d%d",&a,&b);
59             via[a]=1;
60             via[b]=1;
61             join(a,b);
62         }
63     printf("%d\n", sum);
64     }
65     return 0;
66 }
时间: 2024-10-21 14:09:34

More is better--hdu1856(并查集)的相关文章

详解并查集

详解并查集  Powered by WSY in SSF    2019-11-02  13:46 [1]并查集的定义:   并查集(Disjoint  Set)是一种非常精巧的非常实用的数据结构,它主要用来处理一些不相交集合的合并问题,经典的例子有联通子图,最小生成树的克鲁斯-卡尔算法. [2]并查集的经典问题:   我们通常使用“帮派”.“团伙”等问题举例说明并查集.例如帮派问题: 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌

【HDU1856】More is better(并查集基础题)

裸并查集,但有二坑: 1.需要路径压缩,不写的话会TLE 2.根据题目大意,如果0组男孩合作的话,应该最大的子集元素数目为1.所以res初始化为1即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <numeric> 7 #include <

hdu1856 More is better (并查集)

More is better Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 327680/102400 K (Java/Others) Total Submission(s): 19011    Accepted Submission(s): 6998 Problem Description Mr Wang wants some boys to help him with a project. Because the projec

HDU1856 More is better(并查集)

和基本的并查集相比,就是稍微改动了一下. 要求的是每个集合里面人数最多的人数. 就多用一个数组记录这个人数即可. #include<stdio.h> #define N 10000000 int father[N],num[N]; void initial() { int i; for(i=1;i<=N;i++) { father[i]=i; num[i]=1; } } int find(int x) { if(father[x]!=x) father[x]=find(father[x]

并查集(Disjoint Set)

http://www.cnblogs.com/cyjb/p/UnionFindSets.html http://blog.csdn.net/dm_vincent/article/details/7655764 http://blog.csdn.net/dm_vincent/article/details/7769159 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的 Kruskal 算法和

并查集练习1

举头望明月,低头敲代码... 推荐学习地址:http://www.cnblogs.com/cyjb/p/UnionFindSets.html 简单: hdu1213 How Many Tables:新手必秒 1 #include<cstdio> 2 const int N=1001; 3 int f[N]; 4 void init(int n){ 5 for(int i=1;i<=n;++i) 6 f[i]=i; 7 } 8 int fin(int x){ 9 if(x!=f[x])f[

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B

并查集应用

题目描述: One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls

【bzoj3674】 可持久化并查集加强版

http://www.lydsy.com/JudgeOnline/problem.php?id=3674 (题目链接) 题意 维护并查集3个操作:合并:回到完成第k个操作后的状态:查询. Solution 其实就是用主席树的叶子节点维护并查集的可持久化数组fa[]. 细节 终于认识到了按秩合并的强大,单纯写个路径压缩Re飞,写了路径压缩+按秩合并比单纯的按秩合并每快多少→_→ 代码 // bzoj3674 #include<algorithm> #include<iostream>