思路:并查集基本操作了。。。c为1的先把他们并到同一个集合中,然后再检查c=0的情况,如果他们在同一个集合c又等于0说明矛盾。做这题的时候,出现好多小问题(上次写并查集是去年),首先因为输入量很大,cin会超时,要用scanf,其次因为每次读入两个点所以maxn需要开两倍。就这个两个坑。另外注意到b=1e9这个数很多,开不了这么大,所以需要提前离散化一下。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 7;
typedef long long int ll;
struct node{
int a,b,c;
node(){}
node(int a,int b,int c):a(a),b(b),c(c){};
}ans[maxn];
int res[maxn << 1];
int f[maxn << 1];
int find(int x){
return f[x] == x? x : f[x] = find(f[x]);
}
void solved(){
int t;
for(scanf("%d",&t);t;t--){
int n; scanf("%d",&n);
int cnt = 0;
for(int i = 1; i <= n * 2 ; i++)f[i] = i;
for(int i = 1; i <= n; i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
res[++cnt] = x;
res[++cnt] = y;
ans[i] = {x,y,z};
}
sort(res + 1,res + 1 + cnt);
int len = unique(res + 1,res + 1 + cnt) - (res + 1);
bool flag = true;
for(int i = 1; i <= n; i++){
int u = ans[i].a;
int v = ans[i].b;
u = lower_bound(res + 1, res + 1 + len,u) - res;
v = lower_bound(res + 1, res + 1 + len,v) - res;
if(ans[i].c == 1){
int fa = find(u);
int fb = find(v);
if(fa != fb)f[fa] = fb;
}else{
if(find(u) == find(v))flag = false;
}
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
int main(){
solved();
return 0;
}