传送门
题意
(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();
}