解题思路
先满足所有
x
i
=
x
j
x_i=x_j
xi=xj的约束条件,直接用一个并查集维护就行
而对于 x i ≠ x j x_i≠x_j xi=xj 的条件,就判断 x i x_i xi 和 x j x_j xj是否在同一个集合,若在,说明 x i x_i xi本应等于 x j x_j xj ,就矛盾了
然后注意一下,x 的最大值达到 1 0 9 10^9 109 ,所以要使用离散化
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int t,n,fa[1000010],v[3000010],tot=0;
bool flag=1;
struct c{
int x,y,e;
}a[1000010];
int find(int x)
{
if(fa[x]!=x)return fa[x]=find(fa[x]);
else return fa[x];
}
bool cmp(c l,c r){
return l.e>r.e;
}
int main(){
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
flag=1,tot=0;
memset(v,0,sizeof(v));
memset(a,0,sizeof(a));
memset(fa,0,sizeof(fa));
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].e);
v[++tot]=a[i].x,v[++tot]=a[i].y;
}
sort(v+1,v+tot+1);
int len=unique(v+1,v+tot+1)-v;//去重后元素个数
for(int i=1;i<=n;i++)
{
a[i].x=lower_bound(v+1,v+len+1,a[i].x)-v;
a[i].y=lower_bound(v+1,v+len+1,a[i].y)-v;
}
for(int i=1;i<=len;i++)//并查集
fa[i]=i;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
int xx=find(a[i].x),yy=find(a[i].y);
if(a[i].e==1)
fa[xx]=yy;
if(a[i].e==0&&xx==yy)
{
flag=0;
printf("NO\n");
break;
}
}
if(flag)printf("YES\n");
}
}