zoj - 2833 - Friendship

这是一道简单的并查集题目,对于每个人,都先建一棵以他为根的根树,用数组实现树的思想,只要一个fa[]数组就够了,

然后写一个寻找树根的函数,因为我们每次操作都是对树根进行的,再写一个判断函数,判断在同一棵树中的时候,

返回1,不在同一棵树的时候,把层数小的并到层数大的树中,返回0,另外一个数组,保存以每个人为根的朋友数。

就这样了,TLE!(不听老人言,用cin没用scanf)  CE!(点了C提交)   AC!(换回C++提交)偷笑

#include <stdio.h>
#include <string.h>

const int maxn = 100000 + 10;       //最多可能有100000个人

int fa[maxn], cnt[maxn], height[maxn];      //fa[i]为i的朋友,就是树的结点的父亲,cnt[i]为以i为根的朋友数,height[i]为i为根的树的层数

int find(int x)     //寻找x的根,朋友中的老大!!!
{
    while(fa[x] != x)
    {
        x = fa[x];
    }
    return x;
}

int judge(int x, int y)     //判断x与y的关系
{
    int xx = find(x);
    int yy = find(y);
    if(xx == yy)        //如果x与y已在同一棵树中,返回1
        return 1;
    else        //如果x与y不在同一棵树中
    {
        if(height[xx] > height[yy])     //当x所在的树的高度>y所在的树的高度时
        {
            fa[yy] = xx;
            cnt[xx] += cnt[yy];
        }
        else if(height[xx] == height[yy])       //当x所在的树的高度==y所在的树的高度时
        {
            fa[yy] = xx;
            cnt[xx] += cnt[yy];
            height[xx]++;
        }
        else        //当x所在的树的高度<y所在的树的高度时
        {
            fa[xx] = yy;
            cnt[yy] += cnt[xx];
        }
        return 0;
    }
}

int main()
{
    int N, M, i, a, b, count = 1, first = 1;        //N个人,M行数据,输入变量a,b,count为测试组数,first为输出标记(判断是否要空行)
    char c;
    while(scanf("%d%d", &N, &M) != EOF)     //C的写法!
    {
        if(first) first = !first;       //控制第一次不要输出空行,以后每组测试数据都输出一个空行
        else printf("\n");

        printf("Case %d:\n", count++);      //可能觉得除第1组测试数据外,以后的数据输出这行的位置有点别扭,不过,不影响AC!

        for(i = 1; i <= N; i++)     //初始化
        {
            fa[i] = i;      //开始每个人都是一棵根树
            height[i] = 1;      //就只有他自己一层
            cnt[i] = 1;     //就只有他自己一个人,孤独!寂寞!空虚!
        }
		getchar();      //吸收标记,不起影响力数据,但没有不行!
        for(i = 0; i < M; i++)
        {
            scanf("%c", &c);
            if(c == 'M')        //当判断为关系的时候
            {
                scanf("%d%d", &a, &b);
                judge(a, b);
				getchar();      //吸收标记,不起影响力数据,但没有不行!
            }
            else if(c == 'Q')       //当判断为询问的时候
            {
                scanf("%d", &a);
                printf("%d\n", cnt[find(a)]);
				getchar();      //吸收标记,不起影响力数据,但没有不行!
            }
        }
    }
    return 0;
}




posted @ 2012-11-19 18:51  xiaodanding  阅读(130)  评论(0编辑  收藏  举报