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

传送门

题意

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

数据范围

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

题解

点的个数最多有(2 imes 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++)
#define per(i,a,n) for(int i=n-1;i>=1;i--)
#define ll long long

const int N=1e6+10;

int _;

struct node
{
    int x,y,e;
}query[N];

int fa[N];
unordered_map<int,int>rec;
int n,cnt;
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 disperse(int x){
    if(!rec[x]) rec[x]=++cnt;
    return rec[x];
}
void solve()
{
    cin>>n;
    rep(i,1,n+1)
    {
        int x,y,e;
        cin>>x>>y>>e;
        query[i]={disperse(x),disperse(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);
    }
    rep(i,1,n+1)
    {
        if(query[i].e==0)
        {
            if(find(query[i].x)==find(query[i].y))
            {
                cout<<"NO"<<endl;
                return;
            }
        }
    }
    cout<<"YES"<<endl;
}
int main()
{
    cin>>_;
    while(_--) solve();
}
原文地址:https://www.cnblogs.com/hhyx/p/13426776.html