ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF #805(div3) F - Equate Multisets 并查集+二分图?

2022-07-11 21:06:09  阅读:191  来源: 互联网

标签:f1 f2 set int Multisets 查集 CF fa find


给定若干个点对,每个点对包含的数字均在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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有