题目链接:https://www.luogu.org/problemnew/show/P1955
推荐参考博客:https://www.cnblogs.com/cytus/p/8933597.html
这题可以用并查集+离散化做,其中离散化我觉得才是最重要的,如果用map容器来离散化我一直TLE,后来了解了一下怎么离散化,对于有重复元素的序列,我们离散化的时候可以用unique函数,但是用之前必须排序,然后二分来得到离散化之后的编号。
这题思路就是先处理相等的情况,也就是1的情况,然后在处理不相等的情况。
代码:
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<cmath> #include<vector> #include<set> #include<cstdio> #include<string> #include<deque> using namespace std; typedef long long LL; #define eps 1e-8 #define INF 0x3f3f3f3f #define maxn 100005 int pre[2*maxn],b[2*maxn]; int n,m,k,t,cnt; struct node{ int x,y,op; }a[maxn]; void init(int n){ for(int i=0;i<=2*n+1;i++) pre[i]=i; cnt=0; } int find(int x){ return pre[x]=pre[x]==x?x:find(pre[x]); } int main() { scanf("%d",&t); while(t--){ scanf("%d",&n); init(n); int x,y,op,flag=0; for(int i=1;i<=n;i++){ scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].op); b[++cnt]=a[i].x;//把所有元素复制到b数组 b[++cnt]=a[i].y; } sort(b+1,b+cnt+1);//先对b数组排序 int size=unique(b+1,b+cnt+1)-b;//用unique得到不重复的元素个数 for(int i=1;i<=n;i++){ a[i].x=lower_bound(b+1,b+size+1,a[i].x)-b;//二分查找,得到离散化之后的编号 a[i].y=lower_bound(b+1,b+size+1,a[i].y)-b; } for(int i=1;i<=n;i++){ x=a[i].x,y=a[i].y,op=a[i].op; if(a[i].op==1){ int x_fa=find(x); int y_fa=find(y); if(x_fa!=y_fa) pre[x_fa]=y_fa; } } for(int i=1;i<=n;i++){ if(a[i].op==0){ x=a[i].x,y=a[i].y,op=a[i].op; int x_fa=find(x); int y_fa=find(y); if(x_fa==y_fa){ flag=1; break; } } } if(flag) printf("NO\n"); else printf("YES\n"); } return 0; }