二分图 笔记

二分图同时满足 不存在奇数环 和 染色法不矛盾。

二分图的判定:染色法 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 个点至多与 kli 条边相连,右部同理。

kli=kri=1 时,就是二分图的最大匹配。

方法:拆点法 acwing374. 导弹防御塔


最小点覆盖

对任意无向图,存在一最小点集,使每条边都至少有一个端点在该集合中,则称该集合为最小点覆盖。

在二分图中,总有 最小点覆盖 = 最大匹配数

最小点覆盖模型要素:
每条边有两个端点,二者至少选一个

最大独立集

对任意无向图,存在一最大点集,使任意两点间都没有直接的边相连,则称该集合为最大独立集。

在二分图中,
选出最多的点构成独立集 去掉最少的点,使剩下的点之间没有边 用最少的点覆盖所有边

所以,最大独立集 = 总点数 - 最小点覆盖(最大匹配数)

最小路径点覆盖

DAG(有向无环图)中,用最少的不相交的简单路径覆盖图中所有的点,称作最小路径点覆盖。

方法:拆点法构造二分图,DAG 中不存在自环,便可以将所有点拆成 i 和 i',左部表示每个点的出点,右部表示每个点的入点,即若有 u -> v ,在拆点二分图中连 u -> v'

对于点数为 n 的 有向无环图 G 的最小路径点覆盖,有:

路径数 = n - 拆点二分图的最大匹配数

posted @   Zhang_Wenjie  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示