POJ1182(带权并查集)

题目    http://poj.org/problem?id=1182

题解

è¿éåå¾çæè¿°

详细注解在代码中

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 2e5 + 5;

int fa[N];
int n, k;

void init()
{
    for(int i = 1;i <= 3 * n;i ++)
        fa[i] = i;
}

int getf(int x)
{
    if(fa[x] != x)
    {
        fa[x] = getf(fa[x]);
    }
    return fa[x];
}

void Merge(int x,int y)
{
    int dx = getf(x), dy = getf(y);

    fa[dx] = dy;
}

bool check(int x, int y)
{
    return getf(x) == getf(y);
}

int main()
{
    scanf("%d%d",&n,&k);

    init();

    int q, x, y;
    int wrong = 0;

    while(k --)
    {
        scanf("%d%d%d",&q,&x,&y);

        //越界则是错误询问
        if(x < 1 || y < 1 || x > n || y > n)
        {
            wrong ++;
            continue;
        }

        //判断是否是同类
        if(q == 1)
        {
            //判断 如果xy在不同的区域的getf一样  则肯定不是
            if(check(x, y + n) || check(x, y + 2 * n))
            {
                wrong ++;
                continue;
            }
            else
            {
                //否则的话证明他们是同一类
                //把三个区都归为同一类
                Merge(x,y);
                Merge(x + n,y + n);
                Merge(x + 2 * n,y + 2 * n);
            }
        }
        else
        {
            //在同类区或者  跨区域是不能吃的
            if(check(x,y) || check(x,y + 2 * n))
            {
                wrong ++;
                continue;
            }
            else
            {
                //否则是吃与被吃的关系  那么就更新在三个区的关系
                Merge(x,y + n);
                Merge(x + n,y + 2*n);
                Merge(x + 2 *n,y);
            }
        }
    }

    cout << wrong << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Soul_97/article/details/81514526