【模板】一般图最大匹配(带花树算法)/洛谷P6113

1|0题目链接

https://www.luogu.com.cn/problem/P6113

2|0题目大意

给定一个 n 个点 m 条边的无向图,求该图的最大匹配。

3|0题目解析

二分图最大匹配,一般用匈牙利算法完成,图中只存在偶环。

而一般图不能分为左右两部,存在奇环,如何处理奇环,是带花树算法的关键。

若将偶环缩为一点,则该图可以简化为只有奇环的无向图。

对于奇环内部,两两匹配后必定多出一个点不能匹配,则将该点与环外部的点相匹配即可。

通过类似匈牙利算法的多次增广,可以找到最大匹配。

点数为 n,边数为 m

时间复杂度: O(n2m)

4|0参考代码

#include <bits/stdc++.h> using namespace std; const int N = 1005; int n, m, cnt; int fa[N], vis[N], tag[N], pre[N], match[N]; queue <int> q; vector <int> e; vector <int> G[N]; void addEdge(int a, int b, int i) { e.push_back(b); e.push_back(a); G[a].push_back(i); G[b].push_back(i ^ 1); } inline int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);} inline int lca(int x, int y) { ++cnt; while (true) { if (x) { x = find(x); if (tag[x] == cnt) return x; tag[x] = cnt; x = pre[match[x]]; } swap(x, y); } } inline void blossom(int x, int y, int p) { while (find(x) != p) { pre[x] = y; y = match[x]; vis[y] = 1; q.push(y); if (find(x) == x) fa[x] = p; if (find(y) == y) fa[y] = p; x = pre[y]; } } bool bfs(int s) { for (int i = 1; i <= n; ++i) vis[i] = pre[i] = 0, fa[i] = i; while (!q.empty()) q.pop(); q.push(s); vis[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < G[u].size(); ++i) { int v = e[G[u][i]]; if (vis[v] == 2 || find(u) == find(v)) continue; if (!vis[v]) { vis[v] = 2, pre[v] = u; if (!match[v]) { int x = v; while (x) { int y = pre[x], z = match[y]; match[x] = y, match[y] = x; x = z; } return 1; } vis[match[v]] = 1; q.push(match[v]); } else { int p = lca(u, v); blossom(u, v, p); blossom(v, u, p); } } } return 0; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < m; ++i) { int a, b; scanf("%d%d", &a, &b); addEdge(a, b, i << 1); } int ans = 0; for (int i = 1; i <= n; ++i) if (!match[i] && bfs(i)) ans++; printf("%d\n", ans); for (int i = 1; i <= n; i++) printf("%d%c", match[i], i == n ? '\n' : ' '); return 0; }

感谢支持!


__EOF__

本文作者炯炯目光
本文链接https://www.cnblogs.com/jjmg/p/13869334.html
关于博主:KTH 信息与网络工程硕士在读
版权声明:欢迎分享或转载
声援博主:To be or not to be, is a question.
posted @   Chiron-zy  阅读(203)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示