二分图最大匹配
假定图有n个顶点,m条边
给定一个二分图,有左右两个部分,各部分之间的点没有边连接,要求选出一些边,使得这些边没有公共顶点,且边的数量最大
O(nm)
增广路算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| struct augment_path { vector<vector<int> > g; vector<int> pa; vector<int> pb; vector<int> vis; int n, m; int dfn; int res;
augment_path(int _n, int _m) : n(_n), m(_m) { assert(0 <= n && 0 <= m); pa = vector<int>(n, -1); pb = vector<int>(m, -1); vis = vector<int>(n); g.resize(n); res = 0; dfn = 0; }
void add(int from, int to) { assert(0 <= from && from < n && 0 <= to && to < m); g[from].push_back(to); }
bool dfs(int v) { vis[v] = dfn; for (int u : g[v]) { if (pb[u] == -1) { pb[u] = v; pa[v] = u; return true; } } for (int u : g[v]) { if (vis[pb[u]] != dfn && dfs(pb[u])) { pa[v] = u; pb[u] = v; return true; } } return false; }
int solve() { while (true) { dfn++; int cnt = 0; for (int i = 0; i < n; i++) { if (pa[i] == -1 && dfs(i)) { cnt++; } } if (cnt == 0) { break; } res += cnt; } return res; } };
|