二分图 笔记
二分图同时满足 不存在奇数环 和 染色法不矛盾。
二分图的判定:染色法 O(n)
#include <bits/stdc++.h> using namespace std; const int N = 1e3 + 10, M = 2e6 + 10; struct { int to, next; }e[M]; int top, h[N], color[N], n, m; void add(int x, int y) { e[++top] = {y, h[x]}; h[x] = top; } bool dfs(int x, int c) { color[x] = c; for (int i = h[x]; i ; i = e[i].next) { int y = e[i].to; if (!color[y]) if (dfs(y, (c == 1 ? 2 : 1))) return true; else if (color[y] == c) return true; } return false; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 1; i <= m; i ++) { int x, y; cin >> x >> y; add(x, y); add(y, x); } bool flag = false; for (int i = 1; i <= n; i ++) if (!color[i]) if (dfs(i, 1)) { flag = true; break; } cout << (flag ? "No" : "Yes"); return 0; }
最大匹配:匈牙利算法(贪心 + dfs, O(nm) )
① 若二分图中有一子图满足任意两条边没有公共节点,则称为一组匹配。
② 边数最多的子图为该二分图的最大匹配。
③ 增广路:从一非匹配点出发,走交替路(非匹配边 -> 匹配边 -> 非匹配边 ...),最后到达另一非匹配点的路径。
用处 :使当前匹配边数量 + 1,即转换该路径上的匹配边和非匹配边
不断对每个点找增广路增加匹配边,找不到增广路时(等价、判定条件),达到最大匹配。
#include <bits/stdc++.h> #define re register int using namespace std; const int N = 1e3 + 10, M = 5e4 + 10; struct edge { int to, next; }e[M]; int top, h[N]; int a, b, m, ans, match[N]; bool vis[N]; inline void add(int x, int y) { e[++ top] = (edge){y, h[x]}; h[x] = top; return; } bool dfs(int u) { for (re i = h[u]; i; i = e[i].next) { int v = e[i].to; if (vis[v]) continue; vis[v] = true; if (!match[v] || dfs(match[v])) { match[v] = u; return true; } } return false; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> a >> b >> m; for (re i = 1; i <= m; i ++) { int x, y; cin >> x >> y; add(x, y); } for (re i = 1; i <= a; i ++) { memset(vis, false, sizeof(vis)); if (dfs(i)) ans ++; } cout << ans; //最大匹配的边数 return 0; }
最大匹配模型要素:
Ⅰ 节点能分成两个独立的集合, 每个集合内没有边
Ⅱ 每个节点只能与一条匹配边相连
拓展
完备匹配:一二分图左右部均为 N 个节点。若其最大匹配包含 N 条匹配边,则称该图具有完备匹配。
多重匹配(广义的匹配问题):
一二分图左部有 N 个点,右部有 M 个点。
选出尽量多的边,满足左部第 i 个点至多与
当
方法:拆点法 acwing374. 导弹防御塔
最小点覆盖
对任意无向图,存在一最小点集,使每条边都至少有一个端点在该集合中,则称该集合为最小点覆盖。
在二分图中,总有 最小点覆盖 = 最大匹配数
最小点覆盖模型要素:
Ⅲ 每条边有两个端点,二者至少选一个
最大独立集
对任意无向图,存在一最大点集,使任意两点间都没有直接的边相连,则称该集合为最大独立集。
在二分图中,
选出最多的点构成独立集
所以,最大独立集 = 总点数 - 最小点覆盖(最大匹配数)。
最小路径点覆盖
在 DAG(有向无环图)中,用最少的不相交的简单路径覆盖图中所有的点,称作最小路径点覆盖。
方法:拆点法构造二分图,DAG 中不存在自环,便可以将所有点拆成 i 和 i',左部表示每个点的出点,右部表示每个点的入点,即若有 u -> v ,在拆点二分图中连 u -> v'
对于点数为 n 的 有向无环图 G 的最小路径点覆盖,有:
路径数 = n - 拆点二分图的最大匹配数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具