给n组操作,每组操作形式为x y p。
当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。
当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。
输入
输入一个数n表示操作的次数(n<=110^5)
接下来n行每行三个数x,y,p(x,y<=110^8,p=0 or 1)
输出
对于n行操作,分别输出n行YES或者NO
输入样例
3
1 2 1
1 3 1
2 3 0
输出样例
YES
YES
NO
在相等的时候很好维护,直接并查集即可,但是不相等时怎么办呢?
用set维护就可以了,set里面存的与当前不能相等的,每次操作一时,判断一下即可,再维护一下set。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int f[N],n,a[N],x[N],y[N],p[N],cnt,m;
set<int> st[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d %d %d",&x[i],&y[i],&p[i]); a[++cnt]=x[i],a[++cnt]=y[i];
}
sort(a+1,a+1+cnt); m=unique(a+1,a+1+cnt)-a-1;
for(int i=1;i<=m;i++) f[i]=i;
for(int i=1;i<=n;i++){
x[i]=lower_bound(a+1,a+1+m,x[i])-a;
y[i]=lower_bound(a+1,a+1+m,y[i])-a;
}
for(int i=1;i<=n;i++){
if(p[i]){
int fa=find(x[i]),fb=find(y[i]);
if(st[fa].find(fb)!=st[fa].end()) puts("NO");
else if(fa!=fb){
puts("YES");
if(st[fa].size()>st[fb].size()) swap(fa,fb); f[fa]=fb;
for(auto i=st[fa].begin();i!=st[fa].end();i++){
st[*i].erase(fa); st[fb].insert(*i); st[*i].insert(fb);
}
}else puts("YES");
}else{
int fa=find(x[i]),fb=find(y[i]);
if(fa!=fb){
st[fa].insert(fb); st[fb].insert(fa); puts("YES");
}else puts("NO");
}
}
return 0;
}