并查集的最大集合:就是指输入所有关系后,分成了很多的不同集合,最大集合就是那些不同的集合种包含元素最多的集合所包含的元素的多少。
集合个数:就是指输入所有关系后,这些不同集合有多少个。
解决思路:
就是在普通的并查集模板中加入一个记录数组num[],这个数组可以标记每个元素的权值的最大和和最大集合的元素个数。
代码:
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
#define ONF 0xc0c0c0c0
using namespace std;
typedef long long ll;
int par[10000005],num[10000005];
void init(int n)
{
for(int i=1;i<=n;i++)
{
par[i]=i;
num[i]=1;//这里是求最大集合的个数,如果求最后集合中权值最大为多少就让num数组初始化为最开始各个元素的权值。
}
}
int get_par(int x)
{
return par[x]==x?x:par[x]=get_par(par[x]);
}
void doit(int x,int y)
{
int dx=get_par(x);
int dy=get_par(y);
if(dx!=dy)
{
par[dx]=dy;
num[dy]=num[dx]+num[dy];
}
}
int main()
{
int n,x,y;
while(scanf("%d",&n)!=EOF)
{
init(n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&x,&y);
doit(x,y);
}
int Max=0;
int cont=0;
for(int i=1;i<=M;i++)
{
Max=max(Max,num[i]);
if(par[i]==i) //记录最后几个的个数。
++cont;
}
printf("%d %d\n",Max,cont);
}
}
例题:
HDU-1856 More is better
题目:
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.
输入:
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)
输出:
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
样例输入:
4
1 2
3 4
5 6
1 6
4
1 2
3 4
5 6
7 8
样例输出:
4
2
补充:
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.
AC代码:
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
#define ONF 0xc0c0c0c0
using namespace std;
typedef long long ll;
int par[10000005],num[10000005];
void init(int n)
{
for(int i=1;i<=10000005;i++)
{
par[i]=i;
num[i]=1;
}
}
int get_par(int x)
{
return par[x]==x?x:par[x]=get_par(par[x]);
}
void doit(int x,int y)
{
int dx=get_par(x);
int dy=get_par(y);
if(dx!=dy)
{
par[dx]=dy;
num[dy]=num[dx]+num[dy];
}
}
int main()
{
int n,x,y;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
{
printf("1\n");continue;
}
init(n);
int M=0;
for(int i=1;i<=n;i++)
{
scanf("%d %d",&x,&y);
M=max(M,max(x,y));
doit(x,y);
}
int Max=0;
int cont=0;
for(int i=1;i<=M;i++)
{
Max=max(Max,num[i]);
if(par[i]==i)
++cont;
}
printf("%d\n",Max);
}
}