Loading

P1955 [NOI2015]程序自动分析 并查集 离散化

给定n个规则

每个规则 x y z 

z = 1表示 ax = ay  ,z = 0 表示 ax ≠ ay 。

若最后是矛盾的输出NO,否则YES

初开题面是裸的并查集。

再看体面发现 x y的范围 1e9,而n只有1e6,就是说虽然xy很大但是数最多只有1e6个,考虑离散化。

离散化套路:排序,unqiue,lower_bound。

这里数组没有开2倍wa了很久

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define pb push_back
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define moD 1000000003
#define pii pair<int,int>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
typedef  long long ll;
typedef unsigned long long ull;
const ll MOD = 998244353;
const int maxn = 1e6 +5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
using namespace std;

ll mul(ll a, ll b, ll m) {
    ll res = 0;
    while (b) {
        if (b & 1) res = (res + a) % m;
        a = (a + a) % m;
        b >>= 1;
    }
    return res % m;
}

ll quickPower(ll a, ll b, ll m) {
    ll base = a;
    ll ans = 1ll;
    while (b) {
        if (b & 1) ans = mul(ans, base , m);
        base = mul(base, base , m);
        b >>= 1;
    }
    return ans;
}


int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

void Put(ull x)  {
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}

int pre[2 * maxn];
vector<tuple<int,int,int> > p;
vector<int> a;
int Find(int x) {   
    return pre[x] != x ? pre[x] = Find(pre[x]) : x;
}

void Union(int x, int y) {
    int p = Find(x); int q = Find(y);
    if (p != q) pre[q] = p;
}

int main() {
    int n;
    int x, y;
    int e;
    int T = readint();
    while (T--) {
        n = readint();
        a.clear();
        p.clear();
        memset(pre, 0, sizeof pre);
        for (int i = 0; i < n; i++) {
            x = readint(), y = readint();
            e = readint();
            a.push_back(x), a.push_back(y);
            p.emplace_back(x, y, e);
        }
        sort(a.begin(), a.end());
        int len = unique(a.begin(), a.end()) - a.begin();
        for (int i = 1; i <= 2 * len; i++) pre[i] = i;
        for (int i = 0; i < n; i++) {
            if (get<2>(p[i]) == 1) {
                int xx = lower_bound(a.begin(), a.begin() + len, get<0>(p[i])) - a.begin() + 1;
                int yy = lower_bound(a.begin(), a.begin() + len, get<1>(p[i])) - a.begin() + 1;
                if (Find(xx) != Find(yy)) Union(xx, yy);
            }
        }
        int f = 1;
        for (int i = 0; i < n; i++) {
            if (!get<2>(p[i])) {
                int xx = lower_bound(a.begin(), a.begin() + len, get<0>(p[i])) - a.begin() + 1;
                int yy = lower_bound(a.begin(), a.begin() + len, get<1>(p[i])) - a.begin() + 1;
                if (Find(xx) == Find(yy)) {
                    f = 0;
                    break;
                }
            }
        }
        if (f) puts("YES");
        else puts("NO");
    }
}

 

posted @ 2020-07-31 16:54  MQFLLY  阅读(136)  评论(0编辑  收藏  举报