二分图,匹配(学习笔记)

本文详细探讨了二分图的模型要素,包括染色法判断二分图、最大匹配的匈牙利算法应用、最小点覆盖、Konig定理、最大独立集及其与有向无环图最小路径点覆盖的关系。关键结论表明最大匹配数等于最小点覆盖数等价于总点数减去最大独立集或最小路径覆盖。
摘要由CSDN通过智能技术生成

目录

二分图的模型要素:

染色法判断二分图(二部图)

二分图最大匹配

匈牙利算法

二分图的最小点覆盖

konig定理:

二分图的最大独立集:

有向无环图的最小路径点覆盖


重要结论:最大匹配数=最小点覆盖=总点数-最大独立集=总点数-最小路径覆盖 

二分图的模型要素:

1.节点能分成独立的两个集合, 每个集合内部有 0 条边;(二分图模型)
2.每个节点只能与 1 条匹配边相连。(最大匹配模型)

我们把它简称为“0要素”和“1要素” 在把实际问题抽象成二分图匹配时,我们就要寻找题目中具有这种“0”和“1”性质的对象,从而发现模型构建的突破口。

3.每条边有2个端点,二者至少选择一个。我们不妨称之为“2要素”。(二分图最小覆盖模型)

如果一个题目具有“2要素”的特点,那么可以尝试抽象成二分图最小覆盖模型求解
 

染色法判断二分图(二部图)

染色法判定二部图基本思想:
1、任意选择一个节点,将其染成红色
2、循环操作:将红色节点的邻居染成蓝色,将蓝色节点的邻居染成红色
3、若过程中发现任意一节点与其邻居的颜色相同,则该图不是二部图,否则是二部图。

核心代码:


 
int dfs(int u, int c) {
	color[u] = c;
	for (int i = h[u]; i != -1; i = ne[i]) {
		int j = e[i];
		if (!color[j]) {
			if (!dfs(j, 3 - c)) return 0;
		}
		else if (color[j] == c) return 0;
	}
	return 1;
}

二分图最大匹配

372. 棋盘覆盖(匈牙利算法,二分图最大匹配)-CSDN博客

861. 二分图的最大匹配(匈牙利算法, 二分图的最大匹配)-CSDN博客

“任意两条边都没有公共端点”的边的集合被称为图的一组匹配,在二分图中,包含边数最多的一组匹配被称为二分图的最大匹配

对于任意一组匹配 S ( S 是一个边集),属于 S 的边被称为“匹配边”, 不属于 S 的边被称为“非匹配边” 。匹配边的端点被称为“匹配点”, 其他节点被称为“非匹配点”。 如果在二分图中存在一条连接两个非匹配点的路径 path , 使得非匹配边与匹配边在 path 上交替出现,那么称 path 是匹配 S 的增广路, 也称交错路。

增广路显然具有以下性质:

1.长度 len 是奇数。
2.路径上第1,3,5,……, len 条边是非匹配边,第 2,4,6,… ,len-1 条边是匹配边。

正因为以上性质,如果我们把路径上所有边的状态取反,原来的匹配边变成非匹配的,原来的非匹配边变成匹配的,那么得到的新的边集 S` 仍然是一组匹配,并且匹配边数增加了1。进一步可以得到推论:
二分图的一组匹配 S 是最大匹配,当且仅当图中不存在 S 的增广路。

匈牙利算法

1. **初始化:** 对于给定的二分图,将每个顶点的标记初始化为未匹配。

2. **从左侧开始:** 从二分图的左侧开始,对每个未匹配的顶点尝试找到增广路径。

3. **寻找增广路径:** 从当前未匹配的左侧顶点开始,尝试沿着未匹配的边找到增广路径。增广路径是一条交替经过未匹配边和已匹配边的路径。

4. **增广路径存在:** 如果找到增广路径,则根据增广路径更新匹配关系。更新的方式是将路径上的已匹配边变为未匹配,未匹配边变为已匹配。

5. **增广路径不存在:** 如果无法找到增广路径,说明当前左侧顶点已经无法找到匹配,此时需要尝试调整之前的匹配,即修改之前已匹配的边。

6. **调整匹配:** 通过调整匹配,使得右侧的顶点重新可以匹配。具体做法是选择已匹配边中的一条,然后尝试寻找增广路径。

7. **重复步骤2-6:** 重复进行步骤2到步骤6,直到无法找到更多的增广路径为止。

8. **结束:** 当无法再找到增广路径时,算法结束。此时已经找到了二分图的最大匹配。

核心代码:

主函数中的代码:

for (int i = 1; i <= n1; i++) {
		memset(st, 0, sizeof st);
		if (find(i)) {
			ret++;
		}
	}

函数 

 
int find(int u) {
	for (int i = h[u]; i != -1;i=ne[i]) {
		int j = e[i];
		if (!st[j]) {
			st[j] = 1;
         //如果点 j 还没有被匹配,或者find(match[j])能为与j匹配的点找到新的下家
			if (match[j] == 0 || find(match[j])) {
				match[j] = u;
				return 1;
			}
		}
	}
	return 0;
}

二分图的最小点覆盖

376. 机器任务(二分图最小点覆盖,匈牙利算法)-CSDN博客

在二分图中,最小点覆盖问题可以通过最大匹配来解决。二分图是一种图,其中的顶点可以分为两个独立的集合,使得每条边的两个端点分别属于不同的集合。最小点覆盖问题就是要找到最小的顶点集合,使得每条边至少有一个端点在这个集合中。

解决二分图的最小点覆盖问题的常用方法是使用匈牙利算法,它可以找到二分图的最大匹配,然后通过补集得到最小点覆盖。

konig定理:

证明:该文件无法打开 - AcWing

König's theorem(König定理)是图论中的一个重要定理,它描述了二分图的最大匹配和最小顶点覆盖之间的关系。

König's theorem 断言:在任意二分图中,最大匹配的大小等于最小顶点覆盖的大小。(最大匹配数=最小顶点覆盖)

这个定理的证明思路通常是通过构造一个最小顶点覆盖和一个最大匹配之间的一一对应关系。具体地,对于一个二分图,首先构造一个最大匹配,然后通过将所有与最大匹配中的边相关联的顶点都加入到顶点覆盖中,同时对于每个未匹配的顶点,也将其加入到顶点覆盖中。这样构造出来的顶点覆盖集合既是最小的,又能够覆盖所有的边,因此其大小等于最大匹配的大小。

反过来,如果已知一个最小顶点覆盖,可以通过将其中的每个顶点与与之关联的边配对,构造出一个匹配,这个匹配的大小就等于最小顶点覆盖的大小。

综上所述,König's theorem 成立是因为最大匹配的大小等于最小顶点覆盖的大小,这一点在任何二分图中都成立。

构造最小顶点覆盖的一种方法是通过最大匹配来实现。下面是一个具体的构造方法:

1. **找到最大匹配**:首先使用任意的匹配算法(如匈牙利算法)找到二分图的一个最大匹配。

2. **标记未匹配的顶点**:对于未被匹配的顶点,将其标记为未覆盖顶点。

3. **覆盖匹配边的顶点**:对于最大匹配中的每条边,选择其中的一个顶点加入到最小顶点覆盖集合中。

4. **覆盖未匹配的顶点**:对于标记为未覆盖的顶点,也将其加入到最小顶点覆盖集合中。

5. **输出最小顶点覆盖集合**:构造出的顶点集合就是一个最小顶点覆盖。

通过这种方法构造出的顶点集合具有以下性质:

- 它包含了所有的边,因为对于每条边,至少有一个端点被包含在最小顶点覆盖集合中。
- 它是最小的,因为我们从一个最大匹配中选取了尽可能少的顶点,并且添加了标记为未覆盖的顶点以确保覆盖所有的边。

这种方法保证了最大匹配的大小等于最小顶点覆盖的大小,因此符合 König's theorem 的要求。

二分图的最大独立集:

378. 骑士放置(二分图最大独立集,匈牙利算法)-CSDN博客

最大独立集是指图中不相邻的顶点组成的集合中包含顶点数最多的集合。换句话说,最大独立集是图中没有任何边连接的顶点的集合。

在二分图中求解最大独立集相对容易一些,因为二分图的特殊结构使得问题的求解可以简化。

二分图是一种图,其中的顶点可以分为两个独立的集合,使得每条边的两个端点分别属于不同的集合。在二分图中,最大独立集的大小等于图中顶点数减去最大匹配的大小。(定理)

因此,为了求解二分图的最大独立集,可以按照以下步骤进行:

1. 找到二分图的一个最大匹配,可以使用匈牙利算法或其他最大匹配算法来实现。

2. 将图中的所有顶点标记为未覆盖状态。

3. 对于最大匹配中的每条边,将其两个端点都标记为已覆盖状态。

4. 输出所有未被标记为已覆盖状态的顶点,这就构成了最大独立集。

由于二分图的最大匹配与最小顶点覆盖之间存在关系,因此通过求解最大匹配可以方便地得到最大独立集。这个过程保证了最大独立集的大小等于图中顶点数减去最大匹配的大小,从而得到了最大独立集。

有向无环图的最小路径点覆盖

有向无环图(Directed Acyclic Graph,DAG)的最小路径点覆盖问题是指在给定的有向无环图中,找到最小的顶点集合,使得图中的每条路径至少经过该集合中的一个顶点。

解决有向无环图的最小路径点覆盖问题可以通过将其转化为最大匹配问题来解决。具体步骤如下:

1. **构造二分图**:将有向无环图中的每个顶点拆分为两个顶点,分别表示顶点的入点和出点。对于有向边 (u, v),在二分图中添加一条从 u 的出点指向 v 的入点的边。

2. **求解最大匹配**:在构造得到的二分图中,求解最大匹配,即找到尽可能多的不相交的边,使得每个顶点只与一个边相关联。

3. **构造最小路径点覆盖**:根据最大匹配,选择每个匹配的边对应的顶点,作为最小路径点覆盖的顶点集合。因为每个顶点在最大匹配中只与一个边相关联,所以覆盖了所有的路径。

4. **输出最小路径点覆盖集合**:输出构造的最小路径点覆盖集合即可。

这样得到的最小路径点覆盖集合大小就是最小的,使得每条路径至少经过其中一个顶点。

定理:最大匹配数=最小点覆盖=总点数-最大独立集=总点数-最小路径覆盖 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值