[二分图初步]【模板】二分图匹配

题目链接

题目简述:就是二分图板子。

Q:什么是二分图呢?

A:二分图就是一个无向图可以分成两个子集,且满足这个图中每条边的端点都是属于不同子集的。

什么意思呢?上面这个看起来好像有点晦涩难懂,其实这个可以很好地用生活来解释。在现实生活中,每个班级都有那么几对“关系异常”的男女。我们将整个年级中所有这样的人拉出来站在一起,如果发现没有一对是同性的(笑),那么就说明这是一群符合大众道德观(我不歧视同性恋)的早恋学生,那么可以说这群人是符合二分图的定义的。这相当于所有人是一个图,他们之间的情愫就是将他们相连的边,不同的性别为不同的子集,两个子集不相交(双性人太草),且每条边连接着的端点不在同一个子集(如果在的话就有同性恋啦)。

了解了二分图的定义之后,那么二分图会发生那些有趣的事情呢?我们还是依靠上面的模型。首先定义一个词:匹配,也可以称作某条边和它连着的两个点的合称。在这个模型中就相当于是一对情侣的意思。一个图里可以有很多个匹配,就跟一个年级里可能有很多对情侣是一样的(不要早恋!),那么一个图中的匹配满足互不相交的性质,匹配的数量最多的情况叫做最大匹配。这个解释起来也很简单,在把情侣们拉出来后,我们会发现有些渣男/女,与他们相恋的可能有两个或者多个(太草了),这时候大家醋意勃发,要求这些人立刻做出决定终生的选择,也就是相互确立关系,成为匹配。匹配不相交也就是因为都决定终生了就不允许存在三角关系了。

那么为了使这些学生能够得到幸福(早恋是得不到幸福的!),我们就要找到最大子集。那怎么办呢?我们这个时候需要用到一个算法-匈牙利算法。

我们引进一个定义:增广路。但是由于很复杂(有兴趣的自己查),我就直接作出感性的解释。首先我们有着一些标记:与某人确定关系的,以及某人是否正在调换过程中。以下的解释均由男孩子来选女孩子(反过来也是一样的),首先,对于一个男生,他要开始选了,他就找啊找,那么遇到的有两种情况:1.找的女生已经有选择了 2.还没选择。1的话我们要为自己的幸福争取一些机会,于是尝试着请求以下让别人换一个男朋友,那么此时就问男同胞,你能不能再找一个?(此时这个女生已经在调换过程中了,所以男同胞不能再找她),如果能换(函数返回值为一),那么争取到了这一个幸福(横刀夺爱太草),然后你我关系确认一下(户口簿改名字?),再返回1(因为有可能是别人让我换一个,要给别人一个答复),换不了就只有找其他人了。2就直接选就好了(毕竟还能再换)。

那么算法部分已经结束了,要注意一个点:当这个函数不是被自己调用而是主函数调用的时(也就是不是别人让我换,而是我自己要找),一定要清零标记数组!(即是否在调换过程的标记),并且这个标记只标记被选择的哪一方就行了。(要问为什么的话就是这个数组的作用就在于不让男孩子找迷糊了,给他指出哪些是碰不得的,因为别人正等着换)

代码

#include<iostream>
#include<cstdio>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int read(){
    char ch;
    int res=0,f=1;
    ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        res=res*10+(ch-'0');
        ch=getchar();
    }
    return res*f;
}
const int MAXN=20005;
int n,m,e,u,v,ans;
bool is_to[MAXN][MAXN],vis[MAXN];
int l[MAXN],r[MAXN];
bool dfs(int x){
    for(int i=1;i<=m;++i){
        if(!vis[i]&&is_to[x][i]){
            vis[i]=1;
            if(!r[i]||dfs(r[i])){
                r[i]=x;
                l[x]=i;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    n=read();m=read();e=read();
    for(int i=1;i<=e;++i){
        u=read();v=read();
        if(u<=n&&v<=m)is_to[u][v]=1;
    }
    for(int i=1;i<=n;++i)if(!l[i]){
        memset(vis,0,sizeof(vis));
        ans+=dfs(i);
    }
    cout<<ans;
    return 0;
}
View Code

匈牙利算法就是DFS的部分啦。

 

转载于:https://www.cnblogs.com/clockwhite/p/11564465.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值