二分图 笔记
二分图同时满足 不存在奇数环 和 染色法不矛盾。
二分图的判定:染色法 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 个点至多与 \(kl_i\) 条边相连,右部同理。
当 \(kl_i = kr_i = 1\) 时,就是二分图的最大匹配。
方法:拆点法 acwing374. 导弹防御塔
最小点覆盖
对任意无向图,存在一最小点集,使每条边都至少有一个端点在该集合中,则称该集合为最小点覆盖。
在二分图中,总有 最小点覆盖 = 最大匹配数
最小点覆盖模型要素:
Ⅲ 每条边有两个端点,二者至少选一个
最大独立集
对任意无向图,存在一最大点集,使任意两点间都没有直接的边相连,则称该集合为最大独立集。
在二分图中,
选出最多的点构成独立集 \(\Leftrightarrow\) 去掉最少的点,使剩下的点之间没有边 \(\Leftrightarrow\) 用最少的点覆盖所有边
所以,最大独立集 = 总点数 - 最小点覆盖(最大匹配数)。
最小路径点覆盖
在 DAG(有向无环图)中,用最少的不相交的简单路径覆盖图中所有的点,称作最小路径点覆盖。
方法:拆点法构造二分图,DAG 中不存在自环,便可以将所有点拆成 i 和 i',左部表示每个点的出点,右部表示每个点的入点,即若有 u -> v ,在拆点二分图中连 u -> v'
对于点数为 n 的 有向无环图 G 的最小路径点覆盖,有:
路径数 = n - 拆点二分图的最大匹配数

浙公网安备 33010602011771号