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;
}