您的位置:首页 > 其它

51nod 1515 明辨是非[并查集][set]

2017-10-15 20:23 344 查看
对于每一个数分别维护并查集和一个集合

并查集用于判断相等关系

集合用于判断不等关系:每个数的集合中原来为空,如果两个数 x,y 被要求不等就将它们互相插入到集合中,然后这个可以用set实现,按集合(set)中的元素个数大小进行合并(按秩合并)

若p=1,先判断是否在同一个并查集中,若不在则到set中找

若p=0,先判断是否在同一个并查集中,若不在互相插入

#include<cstdio>
#include<algorithm>
#include<set>
#include<map>
#define N 200000
using namespace std;

inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &x)
{
char c=nc(),b=1;
for(;!(c>='0'&&c<='9');c=nc()) if(c=='-') b=-1;
for(x=0;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

int n,cnt=1,fa[N+5];
set<int>s[N+5];
map<int,int>m;

inline int Pos(int x){return m[x]?m[x]:(m[x]=++cnt);}

int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}

int main()
{
read(n);
for(int i=1;i<=n*2;++i) fa[i]=i;
int x,y,opt;
while(n--)
{
read(x),read(y),read(opt);
x=Pos(x),y=Pos(y);
int fx=getf(x),fy=getf(y);
if(opt==1)
{
if(s[fx].count(fy)) puts("NO");
else if(fx!=fy)
{
if(s[fx].size()>s[fy].size()) swap(fx,fy);
fa[fx]=fy;
for(set<int>::iterator pos=s[fx].begin();pos!=s[fx].end();++pos)
s[*pos].erase(fx),s[*pos].insert(fy),s[fy].insert(*pos);
puts("YES");
}
else puts("YES");
}
else
{
if(fx==fy) puts("NO");
else
{
s[fx].insert(fy);
s[fy].insert(fx);
puts("YES");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: