【含义冲突判断】程序自动分析

传送门

题意

\(t\)组样例,\(n\)个数据,每组一个\((x,y,e), e = 1\)表示\(x=y,e=0\)表示\(x≠y\),问是否存在矛盾

数据范围

\(\begin{array}{l}1 \leq n \leq 10^{6} \\ 1 \leq x, y \leq 10^{9}\end{array}\)

题解

点的个数最多有\(2\times 10^{6}\)个,值域是\(10^{9}\),可以进行离散化,便于维护并查集

  • 因为\(x,y\)范围很大所以先将点离散化到小的范围内

  • 必须先将\(x=y\)的所有合并到一个集合,再去判断不相等里面是否有冲突的

  • 再判断不相等的情况如果在一个集合则存在矛盾,否则没有矛盾

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)

const int N = 1e6+10;
int fa[N];
unordered_map <int,int> rc;
int cnt, _;
struct node {
    int x, y, e;
}query[N];
int find(int x) {
    if(fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}
void merge (int a, int b) {
    int pa = find(a), pb = find(b);
    fa[pa] = pb;
}
int get (int x) {
    if(!rc[x]) rc[x] = ++cnt;
    return rc[x];
}
void solve() {
    int n; cin>>n;
    rep(i, 1, n+1) {
        int x, y, e;
        cin>>x>>y>>e;
        query[i] = {get(x),get(y),e};
    }

    rep(i, 1, cnt + 1) fa[i] = i;

    rep(i, 1, n + 1)
        if(query[i].e == 1)
            merge(query[i].x,query[i].y);
    bool unok = 0;
    rep(i, 1, n + 1){
        if(query[i].e == 0){
            int pa = find(query[i].x), pb = find(query[i].y);
            if(pa == pb) { unok = 1; break; }
        }
    }
    if(unok) cout<<"NO"<<endl;
    else cout<<"YES"<<endl;
}

int main() {
    for(cin>>_; _; _--) solve();    
}
posted @ 2020-08-03 15:58  Hyx'  阅读(134)  评论(0编辑  收藏  举报