Hdu-1856 More is better

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1856

题目大意:

就是给你一些树,找出结点数目最多的树。


解题思路:

并查集的简单应用。

开一个boy数组,记录每个结点的子结点个数,如果两棵树合并,则把另一棵树的子结点加在这棵树上即可。

需要注意的就是maxboy的初始化,刚开始初始化为0,悲剧了半天。。如果n=0,则至少还有一个。原题目:or there is only one boy left 特别注意!


代码如下:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 10000010
int pre[MAXN];
int num, maxboy;
int boy[MAXN];

int find(int root) //查找根结点
{
	int son, tmp;
	son = root;
	while(root != pre[root]) //寻找根结点
		root = pre[root];
	while(son != root) //路径压缩
	{
		tmp = pre[son];
		pre[son] = root;
		son = tmp;
	}
	return root;
}

void join(int x, int y)
{
	int root1, root2;
	root1 = find(x);
	root2 = find(y);
	if(root1 != root2)
	{
		pre[root2] = root1;
		boy[root1] += boy[root2];
		maxboy = max(maxboy, boy[root1]);
	}
}

int main()
{
	int x, y;
	while(scanf("%d", &num) != EOF)
	{
		maxboy = 1; //需要注意的地方。。。
		for(int i = 1; i < MAXN; ++i)
		{
			pre[i] = i;
			boy[i] = 1;
		}
		for(int i = 1; i <= num; ++i)
		{
			scanf("%d%d", &x, &y);
			join(x, y);
		}
		printf("%d\n", maxboy);
	}
	return 0;
}

一个牛人写的。。。。还没有怎么看懂。。。。研究研究吧(貌似是离散加输入处理)

#include <iostream>
using namespace std;
const int maxn=10000010;
int    n;
struct NODE
{
    int root;
    int num;
}nod[maxn];

struct SEG
{
    int u, v;
}seg[100001];

int u, v;
int maxsum;

int getfather(int r)
{
    if(nod[r].root==-1)
    return r;
    int temp = nod[r].root;
    nod[r].root=getfather(temp);
    return nod[r].root;
}

void union_set(int r1, int r2)
{
    int root1=getfather(r1);
    int root2=getfather(r2);
    nod[root1].root=root2;
    nod[root2].num += nod[root1].num;
    if(nod[root2].num>maxsum)
    {
        maxsum=nod[root2].num;
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        maxsum=1;
        for (int i=1; i<=n; i++)
        {
              scanf("%d %d",&seg[i].u, &seg[i].v);
              nod[ seg[i].u ].root = -1;
              nod[ seg[i].u ].num=1;
              nod[ seg[i].v ].root =-1;
              nod[ seg[i].v ].num = 1;
        }
        for (int i=1; i<=n; i++)
        {
            if(getfather(seg[i].u)!=getfather(seg[i].v))
            {
                union_set(seg[i].u, seg[i].v);
            }
        }
        printf("%d\n", maxsum);
    }
    return 0;
}


你可能感兴趣的:(JOIN,struct)