【学习笔记】图论
二分图
一个二分图满足有一种划分方案使得它节点的被分为两部分,且所有边的端点所在的部分不相同。即每条边都连接两个部分。显然我们给二分图染色,确定一个点所有点都确定。如果在染的时候发现冲突就代表不是二分图。
一张图是二分图当且仅当其中间没有奇环。
证明:
-
奇环本身就不能染成二分图。
-
如果没有奇环但此图不是二分图,我们需要找出两条从
到 的路径使得通过这两道路径会让 的颜色产生冲突。 -
很明显就是使这两条路径长度奇偶性不同。
-
因为有两条路径,这两条路径一定形成一个环,因为没有奇环,所以这两个路径长度加起来为偶数,所以这两个路径奇偶性相等。
-
也就是说没有奇环的图一定是二分图。
定义一个边集是二分图的匹配,当且仅当边集中任意两条边没有公共端点。即所有边独立。二分图的最大匹配就是最大的匹配数。
增广路:一个二分图的增广路是相对于一个匹配而言的。一条增广路是由匹配边和未匹配边交替出现,并以未匹配点作为开头结尾的路径。此时将匹配和未匹配边取反会发现匹配数加一。那么这条路径称为增广路。
匈牙利算法
我们尝试一个个加入 a 部分的点。假设在加入第
点覆盖
一个图的点覆盖指一个点集使得每条边至少有一个端点在点集内。显然最大点覆盖就是全部点。
二分图的最小点覆盖就是最大匹配数。
证明:
-
首先最大匹配肯定是点覆盖,无论是不是最小。因为如果有一条边两个端点都没连,那么一定可以选这两个点作匹配,则不满足最大匹配定义。
-
也就是说图中有增广路时,选中的点集一定不能覆盖全图。
-
考虑一条匹配边
,其中 在左部, 在右部。若 都能连一个未匹配点,那么会存在增广路。所以假设 能连向未匹配点 ,那么 连向的点一定都是匹配点,所以我们直接把左部或者右部的所有匹配点选了一定满足方案。 -
如果此时少一个点,就代表删掉了这个点的匹配,那么就会出现增广路,则点集一定不会覆盖全图。
-
得证(?)。
最小边覆盖
类比最小点覆盖,就是选择一个尽量小的边集使得所有点都被覆盖。存在边覆盖的前提是没有孤立点。令最小边覆盖为
证明(设总共有
-
假设我们把所有匹配边都选上,还会剩下
个点未被覆盖。 -
因为一个未匹配点不可能连向一个未匹配点,而有边覆盖的图一定没有孤立点,所以每一个未匹配点都有且仅有连向匹配点的边,所以每一个未匹配点都要且可以通过一条边来连。
-
所以总共要连
条边。 -
选择匹配边的原因是每条匹配边都能覆盖两个点且不重复覆盖,根据贪心思想选择匹配边一定最优。
最大独立集
独立集是指选择一些点集使得这些点之间没有连边。令最大独立集为
证明:
-
注意到把非独立集中的点删掉会使得这个图没有一条边,也就是说非独立集是一个点覆盖。
-
所以
。
欧拉图
欧拉图指具有欧拉回路的图。欧拉回路指一条经过图中所有边恰好一次后能够回到起点的路。
半欧拉图指仅具有欧拉通路但不具有欧拉回路的图。欧拉通路指一条能够经过图中所有边恰好一次的路。显然一个图若存在欧拉回路就存在欧拉通路。
欧拉通路一般也叫做欧拉路径,欧拉回路是一种强限制的欧拉路径。
判定欧拉图可以参考小学奥数。
无向图是欧拉图当且仅当有边连接的点连通且每个点度数皆为偶数。
无向图是半欧拉图当且仅当有边连接的点连通且恰好有两个奇度顶点。
有向图是欧拉图当且仅当每个顶点入度和出度相等。
有向图是半欧拉图当且仅当至多一个顶点出度比入度多一,至多一个顶点入度比出度多一,其余顶点入度和出度相等。
求法:遍历当前节点
一个欧拉图取出
tarjan
dfs 搜索树(dfs 生成树)
前置知识。
对图中任意一个点开始访问,保留每个点第一次被访问经过的边构造一棵树。剩下的边可以分为三类:返祖边,即某个节点往祖先节点连的边。前向边,即某个节点往子树中非子节点连的边。横插边,即某个节点往与自己没有祖先后代关系的已访问过的节点连的边。
强连通分量
在有向图中,一个强连通分量是一个点集,满足点集中的任意两点互相可达。强连通分量可以用其中任意一个节点表示(类似并查集的表示方法),也可以新给一个编号。
先构建一棵图的 dfs 搜索树。对于搜索树中的节点
在一遍 dfs 过程中,我们考虑用栈存被访问过的还没有处理强联通分量的点。同时定义
对于一条边
缩点
将有向图中的强连通分量缩成一个点,因为强连通分量中的点互相可达,所以单纯从图的形态表示上是没有问题的。
任何一个有向图缩点后得到的结果都是一个 DAG。
做法就是把所有强连通分量找出来,然后根据原图的连边把不同强连通分量的连边保留即可。
割点
对于无向图来说,割点指将这个点和与这个点相连的边删去后图不连通的点。
仍然考虑
对于节点
割边也叫做桥,没有根节点的特殊判断。
点双
一个图被称作点双,即点双联通图,当且仅当其中所有点都不是割点。
一个无向图中,极大的点双被称为一个点双联通分量,对于极大的定义,就是除自己外没有满足条件的子集包含自己。一个点可能出现在多个不同点双中,但是两个点双一定只有最多一个公共点,此时该点为这两个点双合起来的图的割点,这个显然。对于一个点双,其
如果这个点是割点,首先此时不能往父亲那边划点,那么割点割的方向的子树中的所有仍然可行的节点归到一个点双,并把除了割点以外的所有点归为不可行。
这一步可以用栈解决。如果这个点是搜索树的根,判断其是否为割点,如果是割点按照割点处理,并且每一个子树都是一个割的方向。如果只有一个子树,可以理解其为点双的树根,按照割点处理。如果没有子树,即为单点,单独算作一个点双。
边双
类似点双,一个边双图不存在割边,类似割边比割点好求,边双也比点双好求,把割边删掉后,每一个连通块为一个边双。感性理解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具