链接
题解:
首先是并查集
然后由于 i, j 的范围是[1,1e9],数组不能开这么大,实际上不同数字的个数不会超过2e6,所以离散化
注意:并查集时,先操作所有e=1,再操作所有e=0,
因为
判断答案时,只有出现一种情况时判断为NO,即(fa==fb&&!e)
先操作所有e=1(并)
或者反证,
例:
1 2 0
1 2 1
不是先1后0,会输出YES, 正解NO
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+7;
struct node{
int x,y,e;
}a[maxn];
bool cmp(node tem1,node tem2){
return tem1.e>tem2.e;
}
int b[maxn],dad[maxn];
int seek(int k){
return k==dad[k]?k:dad[k]=seek(dad[k]);
}
int main() {
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int bi=1;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].e);
b[bi++]=a[i].x;
b[bi++]=a[i].y;
}
sort(b+1,b+bi);
int* van=unique(b+1,b+bi);
for(int i=1;i<=n;i++){
a[i].x=lower_bound(b+1,van,a[i].x)-b;
a[i].y=lower_bound(b+1,van,a[i].y)-b;
}
//离散化
//并查集
sort(a+1,a+n+1,cmp);
for(int i=1;i<=2*n;i++)
dad[i]=i;
int flag=1;
for(int i=1;i<=n;i++){
int fa=seek(a[i].x);
int fb=seek(a[i].y);
if(fa==fb&&!a[i].e){flag=0;break;}
if(fa!=fb&&a[i].e){
dad[fa]=fb;
}
}
if(flag)cout<<"YES"<<endl;
else cout << "NO" << endl;
}
return 0;
}