https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1515
给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启发式合并去莽一波就好了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
int n,m,cnt,x,y,op,fa[maxn];
unordered_map<int,int> H;
set<int>s[maxn];
set<int>::iterator it;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int fi(int x)
{
if(x==fa[x])return x;
fa[x]=fi(fa[x]);return fa[x];
}
void set_uni(int x,int y)
{
if(x==y)return;
if(s[x].size()>s[y].size())
{
for(it=s[y].begin();it!=s[y].end();it++)
{
s[x].insert(fi(*it));
s[fi(*it)].erase(y);
s[fi(*it)].insert(x);
}
s[y].clear();
fa[y]=x;
}
else
{
for(it=s[x].begin();it!=s[x].end();it++)
{
s[y].insert(fi(*it));
s[fi(*it)].erase(x);
s[fi(*it)].insert(y);
}
s[x].clear();
fa[x]=y;
}
}
int getid(int x)
{
if(H[x]==0)H[x]=++cnt;
return H[x];
}
void uni(int x,int y)
{
if(s[x].find(y)!=s[x].end()){printf("NO\n");return;}
printf("YES\n");
set_uni(x,y);
}
void spl(int x,int y)
{
if(x==y){printf("NO\n");return;}
printf("YES\n");
s[x].insert(y);
s[y].insert(x);
}
int main()
{
int n;scanf("%d",&n);
for(int i=0;i<maxn;i++)fa[i]=i;
for(int i=1;i<=n;i++)
{
x=read(),y=read(),op=read();
x=fi(getid(x)),y=fi(getid(y));
if(op==1)uni(x,y);
else spl(x,y);
}
}