##题目大意:
题目链接:https://www.luogu.org/problemnew/show/P1955
给出个变量之间的关系(等或不等),求这些活能否全部是真话。
##思路:
考虑并查集,先将读入的排序,给出相等关系的在前,不等关系的在后。那么对于所有相等的两个变量,我们将它们化为同一集合。之后对于不相等的变量,我们看看这两个变量是否在同一集合内,如果在同一集合内,说明这两个变量是相等的,所以肯定不成立;否则成立,继续往下。
但是这样由于变量的名称比较大,所以要离散之后再用并查集。
##代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int t,n,x,y,len,father[200011],b[200011];
struct node{
int x,y,z;
}a[200011];
bool cmp(node x,node y)
{
return x.z>y.z;
}
int find(int x)
{
return father[x]==x?x:father[x]=find(father[x]);
}
int main()
{
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
b[i]=a[i].x;
b[i+n]=a[i].y; //记录变量
}
stable_sort(b+1,b+1+n*2); //排序
len=unique(b+1,b+1+n*2)-b-1; //去重,返回最后数组的长度
for (int i=1;i<=len;i++) father[i]=i;
for (int i=1;i<=n;i++)
{
a[i].x=lower_bound(b+1,b+len+1,a[i].x)-b-1;
a[i].y=lower_bound(b+1,b+len+1,a[i].y)-b-1; //离散
}
stable_sort(a+1,a+1+n,cmp); //排序
for (int i=1;i<=n;i++)
{
int x=find(a[i].x),y=find(a[i].y);
if (a[i].z) //相等关系
if (x!=y)
father[min(x,y)]=max(x,y); //进入同一集合
if (!a[i].z) if (x==y) //不成立
{
printf("NO\n");
break;
}
if (i==n) printf("YES\n");
}
}
}