博客园同步

原题链接

简要题意:

给定两个点集与一些边(保证每条边的顶点属于不同点集),求二分图最大匹配。

解释下:二分图最大匹配 就是 最大的边集使得每两条边都不相交,不共点 的边的个数

那么你会说,我用并查集维护一下就行了?远远不是这样。

本题作为 匈牙利算法 的模板题讲解。

以下面这个关系为例:

假设有 wxqwsqzmxNBLbfwgyxkkk 六个人。

其中,wxqzmxgyxbfw是第一点集,其余是第二点集。

并且他们说:

  • wxq: 我觉得 wsqNBLkkk 都可以成为我的 CP \text{CP} CP。

  • zmx: 我觉得只有 wsq 可以成为我的 CP \text{CP} CP.

  • gyx: 我觉得 wsqNBL 都可以食用。

  • bfw: 我觉得她们三个都不错啊。

好,下面我们要 尽量满足他们的需求

第一个人 wxq,好,他的第一个备选人是 wsq,那么就先让他和 wsq 成为 CP \text{CP} CP.

第二个人 zmx 来了,并对 wxq 说:

你拿走了 wsq 那我怎么办???

wxq 想:行啊,反正我还有 NBLkkk.

于是,wxq被绿了 zmx 成功地 ~绿了wxq 得到了 wsq,然后 wxqNBL 成为 CP \text{CP} CP.

然后,第三个人 gyx 来了,并对 zmx 说:

你拿走了 wsq 那我怎么办?

zmx 想了想说:

我只有她一个备选人啊,我要生存!单身狗还是你做吧

于是 gyx 绿人计划失败

但是 gyx 看自己的备选人还有 NBL,所以对 wxq 说:

喂喂喂,快点还我 NBL.

wxq 想:没关系,反正我还有 kkk 对吧。

所以 wxq又被绿了 gyx 绿了wxq 与 NBL 成为了 CP \text{CP} CP,然后 wxq被轮番绿 与 kkk 成为了 CP \text{CP} CP.

最后一个人 bfw 来了,他先找到 zmx 说:

wsq 给我行不?

zmx 说:我只有她一个人啦!对方拒绝了该请求。

bfw 又辗转来到 wxq 说:

kkk 给我行不?

wxq 说:你们都想绿我是吧,没门 我也只有她一个人了。

bfw 最终对 gyx 说:

救救我,我马上要单身了。

gyx 一口回绝道:我刚刚绿了 wxq,你就像反绿我是吧 我也只有 NBL 一人了,你再找找别人吧。

最后,bfw 成为了单身狗 被抛弃了,他没有 CP \text{CP} CP,所以上述的 二分图最大匹配 为 3 3 3.(满足了 3 3 3 个人的需求)

所以可见,匈牙利算法是一种基于 绿与被绿 协商与匹配的过程。

简要步骤如下:

  1. 如果后来的人 想绿别人 与前面的人发生冲突,前面的人会进行抉择进行第 2 2 2 步;否则后来的人就有了 CP \text{CP} CP. 有了,下一个!

  2. 如果前面的人发现 自己被绿了,还有退路或者能绿别人 自己没有 CP \text{CP} CP 可处,那么就拒绝;然后后来的人回到第 1 1 1 步,进行下一步 准备绿人 。

  3. 如果新来的那人被所有人拒绝了 绿人失败,则它就单着吧。 单身狗它不香吗

众所周知,只有最后绿人成功的人才能获得最终胜利!

有机会上,没机会创造机会也得上!

这就是 匈牙利算法 的大致内容。

你会发现,可能会出现 很多人迭代地绿对方 很多 协商与匹配的过程。 就比方说一个完全图(只有被绿了多次的人才能找到真正的CP,而且先下手为强),所以我们要用 dfs \text{dfs} dfs 进行递归搜索。

  • 细节:

有的时候自己会 间接地绿自己 与自己协商。比方说:

1 1
1 2
2 1
3 1
3 2

1 1 1 和 2 2 2 绿 协商后, 1 → 2 1 \rightarrow 2 1→2, 2 → 1 2 \rightarrow 1 2→1,然后 3 3 3 来了。他 想绿1 先与 1 1 1 协商,然后 1 1 1 与 2 2 2 协商(循环被绿),然后 2 2 2 又和 1 1 1 协商, 1 1 1 又与 2 2 2 协商。。最后3成单身狗,他俩绿疯了 然后就没了。 3:喂你们没人选我么

所以,要用 v i s i vis_i visi​ 表示 当前 想绿人的 与别人协商的是几号,防止循环 绿 协商。

时间复杂度: O ( max ⁡ ( n , m ) × e ) O(\max(n,m) \times e) O(max(n,m)×e)

实际得分: 100 p t s 100pts 100pts.

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;const int N=2e3+1;inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}int n,m,T,vis[N],mat[N];
//mat[i] 表示 i 的 CP 编号
vector<int>G[N]; //图inline bool dfs(int dep,int bs) { //表示当前让 CP 是否成功if(vis[dep]==bs) return 0;vis[dep]=bs;for(int i=0;i<G[dep].size();i++) {int x=G[dep][i];if(!mat[x] || dfs(mat[x],bs)) {//没有匹配 或者 可以让 CP 就换 CPmat[x]=dep; //记录匹配return 1;}} return 0;
}int main(){n=read(),m=read(),T=read();while(T--) {int x=read(),y=read();G[x].push_back(y);} int ans=0;for(int i=1;i<=n;i++)if(dfs(i,i)) ++ans;printf("%d\n",ans); return 0;
}

P3386 【模板】二分图最大匹配 题解相关推荐

  1. 模板--二分图最大匹配

    P3386 [模板]二分图最大匹配 匈牙利算法思想:遍历左部点,对于每个点判断其是否为一条增广路的端点. 核心代码段: 变量解释:a[ i ][ j ]代表左部点与右部点是否有连线,vis为判断是否访 ...

  2. [模板] 二分图最大匹配

    原题链接 #include <iostream> #include <cstring> #include <algorithm>const int N = 510, ...

  3. P3386 【模板】二分图最大匹配

    P3386 [模板]二分图最大匹配 提交71.75k 通过27.33k 时间限制1.00s 内存限制512.00MB 提交答案加入题单 复制题目 题目提供者HOOCCOOH 难度普及+/提高 历史分数 ...

  4. P3386 【模板】二分图最大匹配(匈牙利算法模板)

    题目链接:点击这里 题目大意: 给定一个二分图,其左部点的个数为 nnn ,右部点的个数为 mmm ,边数为 eee ,求其最大匹配的边数. 题目分析: 本题使用的匈牙利算法完成的二分图最大匹配 具体 ...

  5. 【洛谷】P3386 【模板】二分图最大匹配

    题目地址: https://www.luogu.com.cn/problem/P3386 题目描述: 给定一个二分图,其左部点的个数为nnn,右部点的个数为mmm,边数为eee,求其最大匹配的边数.左 ...

  6. 【模板】匈牙利算法 二分图最大匹配题模板

    [任务] 给定一个二分图,用匈牙利算法求这个二分图的最大匹配数. [说明] 求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配. 我们一次枚举左边的点x的所有出边指向的点y, 若y ...

  7. NYOJ 题目239 月老的难题 (二分图最大匹配-匈牙利算法模板)

    月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...

  8. 图论--二分图最大匹配(匈牙利算法)--模板

    //二分图最大匹配数量 #include<cstdio> #include<cstring> #include<iostream> #include<queu ...

  9. P3386二分图最大匹配模版

    传送门 声明几个定义: 1.二分图 对于一个图G=(V,E),若能将其点集分为两个互不相交的两个子集X.Y,使得X∩Y=∅,且对于G的边集V,若其所有边的顶点全部一侧属于X,一侧属于Y,则称图G为一个 ...

最新文章

  1. ASP.NET Core 2 学习笔记(四)依赖注入
  2. 如何使PING命令带上日期,做长久的跟踪
  3. WebSocket服务器上的oTransactionID_SiteDetailMap的qrcode是何时生成的
  4. 【BUG记录】百度人脸识别采集黑屏
  5. 登陆mysql服务器命令_Mysql服务器登陆,启动,停止等基本操作命令介绍(Linux/Centos环境)...
  6. python中input函数的返回是哪种类型_Python3.x中input的变化:input函数默认返回字符串类型...
  7. adsl 路由器默认密码
  8. 服务器电脑 默认虚拟内存,服务器是否需要设置虚拟内存
  9. 如何让电脑开机自启动程序
  10. 数据:42家公司持有超135万枚BTC 价值逾650亿美元
  11. mysql 隐式转换 索引_MySQL性能优化:MySQL中的隐式转换造成的索引失效
  12. 39个SEO经典案例
  13. kubernetes install completed
  14. 渗透tools之Lizard
  15. 激活DataGrip
  16. 数独的Java版解法
  17. 【Luat-esp32】3.陀螺仪-mpu6050
  18. 佐治亚理工计算机考研,[转载]佐治亚理工学院硕士研究生怎么样?申请难度
  19. 电子书资源 Kindle PDF
  20. Linux添加开机自启动应用

热门文章

  1. NGFW的protal认证实验
  2. 解压助手 for Mac(mac解压工具)
  3. python自动化高效办公第二期,带你项目实战【一】{excel数据处理、批量化生成word模板、pdf和ppt等自动化操作}
  4. 织梦仿站标签:dede手机端仿站标签合集
  5. 你把 vite打包 玩明白
  6. 网易云音乐正式登陆Linux平台
  7. Java中的点操作符,分享PDF高清版
  8. 电脑技巧:教你关闭Win11内存压缩,解决电脑卡顿的问题
  9. Windows Server 磁盘空间不足怎么办
  10. mysql 查找小写字母_MySQL中查询时对字母大小写的区分