【LuoguP1955】 [NOI2015] 程序自动分析

链接

传送门

用并查集检验合理性,由于数据较大,需要做一下离散化。

#include <iostream>
#include <cctype>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;
inline int read(){
    
    
    int x = 0, op = 1; char ch = getchar();
    while (!isdigit(ch)){
    
    
        if (ch == '-') op = -1; ch = getchar();}
    while (isdigit(ch)){
    
    
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * op;
}

vector<int> v;
int get(int x){
    
    
    return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
const int N = 1e5 + 10;
int par[N], a[N], b[N], op[N];

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

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

void unit(int i, int j){
    
    
    int x = find(i), y = find(j);
    par[x] = par[y];
}

void solve(){
    
    
    int m = read();
    v.clear();
    for (int i = 1; i <= m; ++i) {
    
    
        a[i] = read(), b[i] = read();
        op[i] = read();
        v.push_back(a[i]);
        v.push_back(b[i]);
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= m; ++i) {
    
    
        a[i] = get(a[i]);
        b[i] = get(b[i]);
    }
    int nn = v.size();
    init(nn);
    int flag = 1;
    for (int i = 1; i <= m; ++i) {
    
    
        if (op[i] == 1) unit(a[i], b[i]);
    }
    for (int i = 1; i <= m; ++i) {
    
    
        if (op[i] == 0 && find(a[i]) == find(b[i])){
    
    
            flag = 0; break;
        }
    }
    printf("%s\n", flag? "YES":"NO");
}

int main() {
    
    
    int cases = read();
    while (cases--){
    
    
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_50070650/article/details/112988211