题目链接

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

题目大意

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

题目解析

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

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

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

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

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

点数为 \(n\),边数为 \(m\) 。

时间复杂度: \(O(n^2 m)\)

参考代码

#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;
}

感谢支持!

最新文章

  1. c++ 一些随笔
  2. js注册验证提示!
  3. spring mvc各种常见类型参数绑定方式以及json字符串绑定对象
  4. wordpress编辑主题时报错Warning: scandir() has been disabled for security reasons in
  5. loadrunner具体实例教你如何进行结果分析
  6. 在Windows7上安装coreseek3.2同时在PHP下简单实现步骤
  7. IOS开发小项目—找色块游戏
  8. js案例_下滑列表
  9. Xcode5.1离线下载安装及使用iOS5模拟器进行开发调试的方法
  10. Spring MVC 中的 forward 和 redirect
  11. HTML5-36d嗨起^_^
  12. 探索 Windows Azure 网站中的自动伸缩功能
  13. poj 1144 Network(割点)
  14. 移动端H5页面遇到的问题总结
  15. java面试集锦
  16. 代理模式(Proxy)
  17. Python使用Tabula提取PDF表格数据
  18. 利用nginx 虚拟主机、请求转发实现不同端口web访问
  19. Session小结
  20. Python开发网站目录扫描器

热门文章

  1. 【SDOI2014】数数(补)
  2. Navicat15 For Mysql最新版完美破解图文教程(支持Win和Mac)
  3. 记录一次因subprocess PIPE 引起的线上故障
  4. 【java+selenium3】自动化截图 (十四)
  5. Flink 实践教程 - 入门(4):读取 MySQL 数据写入到 ES
  6. rabbitMQ报错:Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method:
  7. Dao、Controller、Service三层的结构划分
  8. 痞子衡嵌入式:在IAR开发环境下RT-Thread工程函数重定向失效分析
  9. Linux系统查看磁盘可用空间的5个命令
  10. Spring中常用注解