什么是二分图
匹配有很多种。
我们定义匹配点、匹配边、未匹配点、未匹配边,它们的含 义非常显然。例如图3中1,4,5,7为匹配点,其他顶点为未匹 点;1-5、4-7为匹配边,其他边为非匹配边。
最大匹配&完美匹配
最大匹配:一个图所有的匹配中,所匹配的边数最多 的匹配,称为这个图的最大匹配。图4是一个最大匹 配。 完美匹配:如果一个图的某个匹配中,所有的顶点都 是匹配点,那么它就是一个完美匹配。图 4 是一个完 美匹配。显然,完美匹配一定是最大匹配(完美匹配 的任何一个点都已经匹配,添加一条新的匹配边一定 会与已有的匹配边冲突)。但并非每个图都存在完美 匹配。
交替路:图的一条简单路径,满足任意相邻的两条边, 一条在匹配内,一条不在匹配内 。
增广路:从一个未匹配点出发,走交替路, 如果途径另一个未匹配点(出发的点不算), 则这条交替路称为增广路(agumenting path)。 例如,图 5 中的一条增广路如图 6 所示 (图中的匹配点均用红色标出)
/*==================================================*\ | 二分图匹配(匈牙利算法BFS 实现) | INIT: g[][]邻接矩阵; | CALL: res = MaxMatch (); Nx, Ny 初始化!!! | 优点:适用于稀疏二分图,边较少,增广路较短。 | 匈牙利算法的理论复杂度是O(VE) \*==================================================*/ const int MAXN = 1000; int g[MAXN][MAXN], Mx[MAXN], My[MAXN], Nx, Ny; int chk[MAXN], Q[MAXN], prev[MAXN]; int MaxMatch(void) { int res = 0; int qs, qe; memset(Mx, -1, sizeof(Mx)); memset(My, -1, sizeof(My)); memset(chk, -1, sizeof(chk)); for (int i = 0; i < Nx; i++) { if (Mx[i] == -1) {//对于x集合中的每个没有匹配的点i进行一次bfs找 交错轨 qs = qe = 0; Q[qe++] = i; prev[i] = -1; bool flag = 0;//判断是否找到
下面给出此算法的一个例子
:
(1)置M = 空,对x1-x6标记(*)。
(2)找到交替链(x1, y1)(由标记(x1),(*)回溯得),置M = {(x1, y1)}。
(3)找到交替链(x2, y2)(由标记(x2),(*)回溯得),置M = {(x1, y1), (x2, y2)}。
(4)找到交替链(x3, y1, x1, y4)(图中虚线表示非匹配边, 细实线表示交替链中非匹配边,粗实线表示匹配边),因而得 M = {(x2, y2), (x3, y1),(x1, y4)}。
增广路的重要特点:
1. 有奇数条边 ; 2. 起点在二分图的X边,终点在二分图的Y边 ; 3. 路径上的点一定是一个在X边,一个在Y边,交错出现; 4. 整条路径上没有重复的点 ; 5. 起点和终点都是目前还没有配对的点,其他的点都已经出现在匹配 子图中 ;
6. 路径上的所有第奇数条边都是目前还没有进入目前的匹配子图的 边
,而所有第偶数条边都已经进入目前的匹配子图。奇数边比偶数边多一 条边 ;
7. 于是当我们把所有第奇数条边都加到匹配子图并把条偶数条边都删
除,匹配数增加了1。
我们可以通过不停地找增广路来增加匹配中的匹配边和
匹配点。找不到增广路时,达到最大匹配(这是增广路定理
)。匈牙利算法正是这么做的。
匈牙利算法主要思想
则用(yi)去标记X中结点x。
(2),(3)交替执行,直到下述情况之一出现为止 : (I)标记到一个Y中顶点y,它不是M顶点。这 时从y出发循标记回溯,直到(*)标记的X中 顶点x,我们求得一条增广路。设其长度为 2k+1,显然其中k条是匹配边,k+1条是非匹 配边。 (II)步骤(2)或(3)找不到可标记结点,而又不 是情况(I)。
(5)找到交替链(x4, y3)(由标记(x4),(*)回溯得), M = {(x2, y2), (x3, y1),(x1, y4), (x4, y3)}。
(6)找到交替链(x5, y4, x1, y1, x3, y7)因而得 M = {(x2, y2), (x4, y3),(x5, y4), (x1, y1), (x3, y 7)}
即: 初始化匹配子图为空 While 找得到增广路径 Do 把增广路径添加到匹配子图中
匈牙利算法步聚:
(1) 首先用(*)标记X中所有的非M顶点,然后 交替进行步骤(2),(3)。
(2) 选取一个刚标记(用(*)或在步骤(3)中用 (yi)标记)过的X中顶点,例如顶点xi,如 果xi与y为同一非匹配边的两端点,且在本 步骤中y尚未被标记过,则用(xi)去标记Y 中顶点y。重复步骤,直至寻找到Y或者或 者访问完所有与xi相关点。 (3) 选取一个刚标记(在步骤(2)中用(xi)标记) 过的Y中结点,例如yi,如果yi与x为同一匹 配边的两端点,且在本步骤中x尚未被标记过,
二分图及其应用
(Bipartite Graph & Applications)
主要内容:
什么是二分图? 二分图的各种匹配的定义?
如何利用匈牙利算法求最大匹配?
二分图的最小顶点覆盖 DAG图的最小路径覆盖 二分图的最大独立集
什么是二分图?
二分图又称作二部图,是图论中的一种特殊模型。 设 G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的 子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i 和j分别属于这两个不同的顶点集(i in A,j in B),则称图G 为一个二分图。
(4)当(2),(3)步骤中断于情况(I),则将增广 路中非匹配边改为匹配边,原匹配边改为 非匹配边(从而得到一个比原匹配多一条边 的新匹配),回到步骤(1),同时消除一切 现有标记。 (5)对一切可能,(2)和(3)步骤均中断于情况 (II),或步骤(1)无可标记结点,算法终止(算法 找不到交替链).
算法: 从二分图中找出一条路径来, 让路径的起点和终点都是还没有匹 配过的点,并且路径经过的连线是 一条没被匹配、一条已经匹配过交 替出现。 找到这样的路径后,显然路径 里没被匹配的连线比已经匹配了的 连线多一条,于是修改匹配图,把 路径里所有匹配过的连线去掉匹配 关系,把没有匹配的连线变成匹配 的,这样匹配数就比原来多1个。 不断执行上述操作,直到找不 到这样的路径为止。
A
B
什么是二分图?
二分图的一个等价定义:不含有(含奇数条边
的环)的图。图1是一个二分图。为了清晰,我们都 把它画成图2的形式。 无向图G为二分图的充分必要条件是,G至少有 两个顶点,且其所有回路的长度均为偶数
匹配
在图论中一个匹配是一个边的集合,其中任意 两条边都没有公共顶点。例如,图3中红色的边。