51nod 1515 明辨是非 并查集+set维护相等与不等关系
Posted jackpei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1515 明辨是非 并查集+set维护相等与不等关系相关的知识,希望对你有一定的参考价值。
考试时先拿vector瞎搞不等信息,又没离散化,结果好像MLE;后来想起课上讲过用set维护,就开始瞎搞迭代器。。。QWQ我太菜了。。
用并查集维护相等信息,用set记录不相等的信息:
如果要求变量不等,若不和并查集矛盾,就拿set互相记录一下,YES;矛盾就NO
如果要求变量相等,
1.x记录的不等的变量中有y,说明矛盾,NO
2.若祖先不等,那就合并两个变量所在的并查集(合并两个并查集的祖先),size大的并到小的上,set暴力转移集合不相等的信息,YES
否则YES
#include<cstdio> #include<iostream> #include<map> #include<set> #define R register int using namespace std; int n,cnt; set<int> s[200010]; map<int,int>mp; int fa[200010]; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int getf(int x) {return x==fa[x]?x:fa[x]=getf(fa[x]);} signed main() { n=g(); for(R i=1;i<=n*2+1;++i) fa[i]=i; for(R i=1;i<=n;++i) { R x=g(),y=g(),p=g(); if(mp[x]) x=mp[x]; else x=mp[x]=++cnt; if(mp[y]) y=mp[y]; else y=mp[y]=++cnt; x=getf(x),y=getf(y); if(s[x].size()<s[y].size()) swap(x,y); if(p&1) { if(s[x].count(y)) putchar(‘N‘),putchar(‘O‘),putchar(‘ ‘); else if(x!=y) { fa[y]=x; for(set<int>::iterator it=s[y].begin();it!=s[y].end();it++) s[*it].insert(x),s[x].insert(*it); putchar(‘Y‘),putchar(‘E‘),putchar(‘S‘),putchar(‘ ‘); } else putchar(‘Y‘),putchar(‘E‘),putchar(‘S‘),putchar(‘ ‘); } else { if(x==y) putchar(‘N‘),putchar(‘O‘),putchar(‘ ‘); else s[x].insert(y),s[y].insert(x), putchar(‘Y‘),putchar(‘E‘),putchar(‘S‘),putchar(‘ ‘); } } }
2019.04.11
以上是关于51nod 1515 明辨是非 并查集+set维护相等与不等关系的主要内容,如果未能解决你的问题,请参考以下文章