「题解」洛谷 P1955 [NOI2015]程序自动分析

题目

P1955 [NOI2015]程序自动分析

简化题意

给你一些相等不相等的关系,问你合不合法。

思路

并查集。

用并查集把相等的都放到一个连通块中,不相等的关系判断是否在一个连通块内。

需要离散化。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 1100011

int t, n, fa[MAXN << 1];
struct query {
    int x, y, typ;
    friend bool operator < (query q1, query q2) {
        return q1.typ > q2.typ;
    }
}q[MAXN];
struct lsh {
    int w, id, typ;
    friend bool operator < (lsh l1, lsh l2) {
        return l1.w < l2.w;
    }
}l[MAXN << 1];

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

void Union(int x, int y) {
    int rootx = find(x), rooty = find(y);
    if (rootx == rooty) return;
    fa[rootx] = rooty;
}

int main() {
    scanf("%d", &t);
    while (t--) {
        int cnt = 0;
        bool f = 1;
        scanf("%d", &n);
        for (int i = 1; i <= 2 * n; ++i) fa[i] = i;
        for (int i = 1; i <= n; ++i) {
            scanf("%d %d %d", &q[i].x, &q[i].y, &q[i].typ);
            l[++cnt].w = q[i].x, l[cnt].typ = 1, l[cnt].id = i;
            l[++cnt].w = q[i].y, l[cnt].typ = 0, l[cnt].id = i;
        }
        std::sort(l + 1, l + cnt + 1);
        for (int i = 1, now = 0; i <= cnt; ++i) {
            if (l[i].w != l[i - 1].w) ++now;
            if (l[i].typ == 1) q[l[i].id].x = now;
            else q[l[i].id].y = now;
        }
        std::sort(q + 1, q + n + 1);
        for (int i = 1; i <= n; ++i) {
            if (q[i].typ == 1) Union(q[i].x, q[i].y);
            else {
                if (find(q[i].x) == find(q[i].y)) {
                    f = 0;
                    puts("NO");
                    break;
                }
            }
        }
        if (f) puts("YES");
    }
    return 0;
}
posted @ 2020-08-31 17:05  yu__xuan  阅读(153)  评论(0编辑  收藏  举报