并查集。
一眼傻逼题,直接离线把一样的合并按不一样的判断即可。
然后30。
发现要离散。
然后50。
空间要开两倍。
//Twenty #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<ctime> #include<queue> using namespace std; typedef long long LL; const int maxn=1e5+5; const int mod=1e9+7; int T,n,sza,szb,a[maxn*2][2],b[maxn*2][2],fa[maxn*2],ls[maxn*2],sz; void read(int &ret) { int f=1; ret=0; char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); if(ch=='-') f=-1,ch=getchar(); for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0'; ret*=f; } int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } int hs(int x) { return lower_bound(ls+1,ls+sz+1,x)-ls; } int ck() { sort(ls+1,ls+sz+1); int tpsz=unique(ls+1,ls+sz+1)-(ls+1); sz=tpsz; for(int i=1;i<=2*n;i++) fa[i]=i; for(int i=1;i<=sza;i++) { int x=hs(a[i][0]),y=hs(a[i][1]); int u=find(x),v=find(y); if(u==v) continue; fa[u]=v; } for(int i=1;i<=szb;i++) { int x=hs(b[i][0]),y=hs(b[i][1]); int u=find(x),v=find(y); if(u==v) return 0; } return 1; } void init() { read(T); while(T--) { int x,y,z; sza=0; szb=0; sz=0; read(n); for(int j=1;j<=n;j++) { read(x); read(y); read(z); ls[++sz]=x; ls[++sz]=y; if(z==1) { a[++sza][0]=x; a[sza][1]=y; } else { b[++szb][0]=x; b[szb][1]=y; } } if(ck()) printf("YES "); else printf("NO "); } } int main() { init(); return 0; }