学习笔记 二分图
二分图的定义
如果一张无向图的 N 个节点(N ≥ 2) 可以分成 A,B 两个非空集合,其中A∩B=Ø,并且在同一个集合内的点之间都没有边相连,那么称这张无向图为一张二分图。A,B 分别称为二分图的左部和右部。
二分图的一些性质:
1.图中不存在奇环。(证明,二分图构成环,必然是 A-B-A 之类的,此时环的长度必然为偶数。证毕。)
2.一张无向图是二分图,当且仅当图中不存在奇环。
关于性质2的证明,我们可以考虑使用染色法。首先,若图中存在奇环,则不可能是二分图。当图中不存在奇环,此时我们对图中的每个点用黑白两种颜色标记,黑色表示二分图的左部点,白色表示二分图的右部点。当一个节点被标记后,它的所有相邻节点标记成与它相反的颜色。因为不存在奇环,对于一个不是环的路径,必定可以做到黑白黑白黑白……这样的标记,满足二分图的定义。而对于一个偶环,我们也能够做到黑白黑白黑这样的标记(可以画图尝试)。因此当不存在奇环是,这个无向图就是二分图。
二分图的判定:
我们仍然可以用染色法。若标记过程中产生冲突,说明存在奇环,该图不是二分图。若标记成功,说明不存在奇环,该图是二分图。染色法一般基于深度优先遍历实现,时间复杂度为(N+M),其代码如下:
int flag=1; void dfs(int x,int color){ v[x]=color;//赋值 for(int i=head[x];i;i=Next[i]){ int y=ver[y]; if(!y) dfs(y,3-color); else if(v[y]==color) flag=0; } }
二分图最大匹配(此处参考lyd的蓝书)
定义:"任意两条边都没有公共端点"的边的集合被称为图的一组匹配。在二分图中,包含边数最多的一组匹配被称为二分图的最大匹配。
对于任意一组匹配 S ( S 是一个边集),属于S的边被称为"匹配边",不属于 S 的边被称为“非匹配边”。匹配边的端点被称为“匹配点”,其他节点被称为“非匹配点”。
增广路
定义:如果在二分图中存在一条连接两个非匹配点的路径 path,使得非匹配边与匹配边在 path 上交替出现,那么称 path 是匹配 S 的增广路,也称交错路。
性质:1.长度 len 是奇数;2.路径上第奇数条边是非匹配边,第偶数条边是匹配边。
增广路的推论:二分图的一组匹配 S 是最大匹配,当且仅当图中不存在 S 的增广路。
浅析一下:基于增广路的性质,如果我们把路径上的所有边的状态取反,原来的匹配边变成非匹配边,原来的非匹配边变成匹配的,那么得到的边集 S' 仍然是一组匹配,并且匹配边数增加了1。因此当存在增广路是,必定能找到一组更优的匹配。证毕。
匈牙利算法(增广路算法)
用途 :计算二分图最大匹配
主要过程:
1.设 S=Ø,即所有边都是非匹配边;
2.寻找增广路path,把路径上所有边的匹配状态取反,得到一个更大的匹配 S';
3.重复第2步,直至图中不存在增广路。
对于该过程的实现,我们可以枚举每一个左部点 x ,尝试为每个 x 寻找一个匹配的右部节点 y。
找到的这个节点 y 必须满足以下两个条件之一。
1. y 本身就是非匹配点。 2. y 已经与左部点 x' 匹配,但能从 x' 出发能找到另一个右部点 y'。
实现方法如下:
bool dfs(int x){ for(int i=head[x];i;i=Next[i]){ if(!vis[y=ver[i]]){ vis[y]=1; int t=match[y]; if(!t||dfs(t)){ match[y]=x; return true; } } } return false; } for(int i=1;i<=n;++i){//在main函数中 memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; }
匈牙利算法的正确性基于贪心策略,它的一个重要特点是:当一个节点成为匹配点后,至多因为找到增广路而更换匹配对象,但是绝对不会变成非匹配点。
对面每个左部节点,寻找增广路最多便利整张二分图一次。因此,该算法的时间复杂度使O(NM)。
建模
二分图匹配的模型有两个要素:1.节点能分成独立的两个集合,每个集合内部有0条边;2.每个节点只能与一条匹配边相连。
完备匹配
给定一张二分图,其左部、右部节点数相同,均为N个节点。如果该二分图的最大匹配包含N个匹配便,则称该二分图均有完备匹配。
二分图最小点覆盖
给定一张二分图,求出一个最小的点集 S,使得图中任意一条边都有至少一个端点属于 S。这个问题被成为二分图的最小点覆盖,简称最小覆盖。
König定理:二分图最小点覆盖包含的点数等于二分图最大匹配包含的边数(证明略)
二分图的最大独立集
给定一张无向图 G =(V,E),满足下列条件的点集 S 被称为图的独立集。
1. S ⊆ V
2. ∀ x,y ∈ S , (x , y) ∉ E
通俗的讲,图的独立集就是“任意两点之间都没有边相连”的点集。包含点数最多的一个就是图的最大独立集。
对应地,“任意两点之间都有一条边相连”的子图被称为无向图的“团”。点数最多的团被称为图的最大团。
定理1:无向图G的最大团等于其补图G'的最大独立集。(正确性显然)
注:G' = (V , E') 被称为 G=(V , E ) 的补图,其中 E'={(x , y) ∉ E } 。
定理2:设G是有n个节点的二分图,G的最大独立集的大小等于n减去最大匹配数。
证明:
选出最多的点构成独立集
< = > 在图中去掉最少的点,使剩下的点没有边
< = > 用最少的点覆盖所有的边。
因此,去掉二分图的最小点覆盖,剩余的点就构成二分图的最大独立集。而最小点覆盖数等于最大匹配数,故最大独立集大小等于 n 减去最大匹配数。
证毕。
有向无环图的最小路径点覆盖
给定一张有向无环图,要求用尽量少的不相交的简单路径,覆盖有向无环图的所有顶点(也就是每个顶点恰好被覆盖一次)。这个问题被称为有向无环图的最小路径点覆盖,简称“最小路径覆盖”。
设原来的有向无环图为 G = (V , E),n=|V|。把 G 中的每个点 x 拆成编号为 x 和 x+n 的两个点。建立一张新的二分图, 1~n作为二分图左部点,n+1~2n 作为二分图右部点,对于原图的每条有向边(x , y),在二分图的左部点 x 和右部点 y+n 之间连边。最终得到的二分图称为 G 的拆点二分图,记为 G2。
定理:有向无环图的最小路径点覆盖包含的路径条数,等于 n 减去拆点二分图 G2 的最大匹配数。
证明:
在有向无环图 G = (V , E)的最小路径覆盖中,对于任意 x ∈ V ,因为路径不相交,所以 x 的入度和出度都不超过1。因为每个节点都被覆盖,所以 x 的入度和出度至少有一个是1。
因此,最小路径覆盖中的所有边,在拆点二分图 G2 中构成一组匹配。最小路径覆盖中每条边 (x , y) 的起点 x 与而二分图每条匹配边 (x , y+n) 的左部点 x 是一一对应的。
特别地,对于每条路径的终点 t,因为 t 没有出边,所以在二分图中,t 匹配失败。即路径的终点和二分图左部的非匹配点是一一对应的。
路径覆盖包含的路径条数最少
<=> 路径的终点数(出度为 0 的点数)最少
<=> 二分图左部非匹配点最少
故 G 的最少路径覆盖的路径数等于 n 减去拆点二分图 G2 的最大匹配数。
证毕。
最小路径可重复点覆盖
给定一张有向无环图,要求用尽可能少的可相交的简单路径,覆盖有向无环图的所有顶点(也就是一个节点可以被覆盖多次)。这个问题被称为有向无环图的最小路径可重复点覆盖。
在最小路径可重复点覆盖中,若两条路径 …->u->p->v->…和…->x->p->y->…在点 p 相交,则我们在原图中添加一条边 (x , y),让第二条路径直接走 (x , y),就可以避免重复覆盖点p。
进一步地,如果我们把原图中所有间接连通的点对 x , y 直接连上有向边 (x , y),那么任何“有路径相交的点覆盖”一定可以转化成“没有路径相交的点覆盖”。
综上所述,有向无环图 G 的最小路径可重复点覆盖,等价于先对有向图传递闭包,得到有向无环图 G',再在 G' 上求一般的(路径不可相交的) 最小路径点覆盖。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】