https://www.51nod.com/Challenge/Problem.html#!#problemId=1515
注意这题跟种类并查集不沾边 因为a!=b&&b!=c推不出a==c
对于每个集合u 把所有与u不等的集合v1 v2...都存入一个vector 在合并u与v时 对其中vector元素较少的一个进行遍历 判断是否包含另一个集合 即启发式合并
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define pb push_back
const int maxn=1e5+10;
struct node
{
int x,y,p;
};
node order[maxn];
vector <int> pre[2*maxn];
int ary[2*maxn],f[2*maxn];
int n,len;
int getf(int p)
{
if(f[p]==p) return p;
else return f[p]=getf(f[p]);
}
int main()
{
int i,j,fx,fy;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d%d",&order[i].x,&order[i].y,&order[i].p);
ary[2*i-1]=order[i].x,ary[2*i]=order[i].y;
}
sort(ary+1,ary+2*n+1);
len=unique(ary+1,ary+2*n+1)-ary-1;
for(i=1;i<=n;i++){
order[i].x=lower_bound(ary+1,ary+len+1,order[i].x)-ary;
order[i].y=lower_bound(ary+1,ary+len+1,order[i].y)-ary;
}
for(i=1;i<=len;i++){
f[i]=i;
}
for(i=1;i<=n;i++){
fx=getf(order[i].x),fy=getf(order[i].y);
if(order[i].p==1){
if(fx!=fy){
if(pre[fx].size()<pre[fy].size()){
swap(fx,fy);
}
for(j=0;j<pre[fy].size();j++){
if(getf(pre[fy][j])==fx) break;
}
if(j==pre[fy].size()){
for(j=0;j<pre[fy].size();j++){
pre[fx].pb(pre[fy][j]);
}
f[fy]=fx;
printf("YES\n");
}
else printf("NO\n");
}
else printf("YES\n");
}
else{
if(fx!=fy){
pre[fx].pb(fy),pre[fy].pb(fx);
printf("YES\n");
}
else printf("NO\n");
}
}
return 0;
}