【学习笔记】二分图
二分图の知识总理
First. 定义
万事都先需了解定义
简单来说,二分图(二部图)就是一种满足以下性质的图:
- 点集
的两个不相交子集 和 可以组成这个图,且两个子集中,同集合的点之间没有任何边连接。 - 将两集合一个染黑,一个染白,每条边一定连接着一黑一白点。
(常用于判定二分图)
Second. 判定
如果判断不出一个图是否为二分图,就不能使用二分图的性质了。
Part.1 染色法
随便选取一个节点,将其染成黑色,接着将与它相连的点染成相反的颜色,如果出现了染色覆盖,那么此图不为二分图
Part.2 判奇环
使用bfs或dfs扫一遍图,如果存在奇环则不为二分图。
由性质三易证
Third.应用
Part.1 二分图最大匹配
肥肠重要,根本的根本,几乎所有二分图的题都会用到
最大匹配顾名思义就是最大的匹配,那什么是匹配呢?
接下来需要引入
在图论中,假设图 G=(V,E),其中 V 是点集,E 是边集。
一组两两没有公共点的边集
称为这张图的 匹配。
定义匹配的大小为其中边的数量
,其中边数最大的 为 最大匹配。
当图中的边带权的时候,边权和最大的为 最大权匹配。
匹配中的边称为 匹配边,反之称为 未匹配边。
而 二分图最大匹配就是二分图中,边数最大的匹配。
前面掰掰了那么多定义,现在,该讲讲如何用算法来解决二分图最大匹配。
Algorithm.1 匈牙利算法
对于这个算法,我们还要引入一个概念怎么那么多概念啊:
对于一条由未匹配边、匹配边交错组成,且一未匹配边为始、未匹配边为终的路径即为
。 由于增广路未匹配边一定比匹配边多
,所以每次将增广路上的未匹配边与匹配边互换,匹配边就多了一。 由此可以得到,一直去寻找
,即为求得最大匹配。
Code
int link[MAXN];//储存匹配边
bool road[MAXN];//标记是否走过
bool find(int x){
for(auto i:G[x]){
if(!road[i]){
road[i] = 1;
if(link[i] == 0||find(link[i])){//增广路交替的样子体现在这里
link[i] = x;
return true;
}
}
}
return false;
}
int find_max(){
int ans = 0;
For(i,1,n){
For(i,1,m) road[i] = 0;
if(find(i)) ans ++;
}
return ans;
}
Algorithm.2 Dinic
还没学呢
Part.2 二分图最小点覆盖
定义
选最少的点,满足每条边至少有一个端点被选
我们需要引入一个定理:
一个二分图的最大匹配数等于这个图的最小点覆盖数。
所以我们只需要求出最大匹配数就能得到最小点覆盖数。
经典题目
- NKOJ P1524 柯南开锁
Part.3 二分图的最小路径覆盖
定义
在图中找一些路径,这些路径覆盖图中所有的顶点,且路径间无交点
定理:
二分图最小路径覆盖=顶点总数
二分图的解题方式
First. 寻
我们需要在题目中找出什么是
EG.1
NKOJ P2092 魏
此题的集不再是一个点,而是一条边,也就是曹操每次走的路径,而 集就是郭嘉的任务点。
Second. 建
寻找
EG2
P1963 [NOI2009] 变换序列 - 洛谷
此题需要通过距离以及 的计算公式来建立 与 之间的关系,连接出4条边。
Third. 判
判断此题为什么类型(最小点覆盖、最大匹配、最小路径覆盖),代入公式计算。
个人见解
我认为以上三个步骤中哪一步都不能少,其中有一些题目“寻”很难,比如:
P1263 [CEOI2002] Royal guards - 洛谷
它需要将连通的空地视为一块,将横列纵列分别标号,将纵列与横列相交的地方是空地的地方连边。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效