51Nod-1515-明辨是非

ACM模版

描述

描述

题解

这里主要涉及到相等和不相等以及不确定关系三种,初始化全部是不确定关系,通过 n 组操作对其进行修改,所有有效操作(YES)都会改变其不确定性关系,那么我们可以通过两种数据结构来表示这关系,相等的关系很容易想到,就是并查集,相等的我们并入一个并查集即可,那么不相等关系我们可以通过 set 来维护,这样我们就可以充分的表现任意两者之间的关系了。另外这里需要用到离散化,也就是用 map 打打标签,毕竟 x y 都太大了。

代码

#include <cstdio>
#include <set>
#include <map>

using namespace std;

const int MAXN = 2e5 + 10;

int n, cnt = 1;
int pre[MAXN];
set<int> si[MAXN];
map<int, int> mii;

int find(int x)
{
    return pre[x] == x ? x : pre[x] = find(pre[x]);
}

int main()
{
    scanf("%d", &n);
    n <<= 1;
    for (int i = 1; i <= n; i++)
    {
        pre[i] = i;
    }
    n >>= 1;

    int x, y, p;
    while (n--)
    {
        scanf("%d%d%d", &x, &y, &p);
        if (mii[x])
        {
            x = mii[x];
        }
        else
        {
            x = mii[x] = ++cnt;
        }
        if (mii[y])
        {
            y = mii[y];
        }
        else
        {
            y = mii[y] = ++cnt;
        }

        int u = find(x), v = find(y);
        if (p == 1)
        {
            if (si[u].count(v)) //  u 和 v 限制不相等
            {
                puts("NO");
            }
            else if (u != v)    //  未限制但并未相等
            {
                if (si[u].size() > si[v].size())
                {
                    swap(u, v);
                }
                pre[u] = v;
                for (auto it = si[u].begin(); it != si[u].end(); it++)
                {
                    si[*it].insert(v);
                    si[v].insert(*it);
                }
                puts("YES");
            }
            else
            {
                puts("YES");
            }
        }
        else
        {
            if (u == v)
            {
                puts("NO");
            }
            else
            {
                si[u].insert(v);
                si[v].insert(u);
                puts("YES");
            }
        }
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值