CF #805(div3) F - Equate Multisets 并查集+二分图?
作者:互联网
给定若干个点对,每个点对包含的数字均在1-n之间
要求把这些点对分到两个set里面,使得每个set里面的n不重复
(话说我的第一反应是2-set然后慌张自己2-set不会打嘿嘿嘿)
一般这种匹配,冲突,点,都和图论有点关系
和图论有点关系就是要建图啦
俺的建图是把数字看成一个节点,如果存在点对,比如(1,2),则在1和2之间连边
然后玩一下样例,发现如果存在奇数环(环的长度为奇数),必然无解
我先写了个dfs判断环,但由于太久没码,码力down~down,挂了
遂怒写并查集,如果两个点之间有边,直接合并起来,如果集合的个数都是偶数,就有解(和dfs其实是一样的,本质是判断有没有奇数环)
#include<bits/stdc++.h> using namespace std; int n,fa[3*100007],sum[3*100007],book[3*100007]; int find(int u) { if(fa[u]!=u) return fa[u]=find(fa[u]); else return u; } void init() { for(int i=1;i<=n;i++) { fa[i]=i;sum[i]=1;book[i]=0; } } int main() {int t; //freopen("lys.in","r",stdin); cin>>t; while(t--) { cin>>n; init(); for(int i=1;i<=n;i++) { int a,b; cin>>a>>b; book[a]++;book[b]++; int f1=find(a),f2=find(b); if(f1!=f2) { fa[f1]=f2; sum[f2]+=sum[f1]; } } int ok=0; for(int i=1;i<=n;i++) { if(book[i]>2) { ok=1; cout<<"NO"<<endl; break; } } if(ok==1) continue; ok=0; for(int i=1;i<=n;i++) { int f=find(i); // cout<<i<<" "<<f<<" "<<sum[f]<<endl; if(sum[f]%2==1) { ok=1; } } if(ok==0) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } } }
标签:f1,f2,set,int,Multisets,查集,CF,fa,find 来源: https://www.cnblogs.com/liyishui2003/p/16467853.html