题目链接

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

感谢支持!

【模板】一般图最大匹配(带花树算法)/洛谷P6113的更多相关文章

  1. HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力

    一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...

  2. ZOJ 3316 Game 一般图最大匹配带花树

    一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...

  3. 【UOJ #79】一般图最大匹配 带花树模板

    http://uoj.ac/problem/79 带花树模板,做法详见cyb的论文或fhq的博客. 带花树每次对一个未盖点bfs增广,遇到奇环就用并查集缩环变成花(一个点),同时记录每个点的Next( ...

  4. 【learning】一般图最大匹配——带花树

    问题描述 ​ 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...

  5. UOJ #79 一般图最大匹配 带花树

    http://uoj.ac/problem/79 一般图和二分图的区别就是有奇环,带花树是在匈牙利算法的基础上对奇环进行缩点操作,复杂度似乎是O(mn)和匈牙利一样. 具体操作是一个一个点做类似匈牙利 ...

  6. 【UOJ 79】 一般图最大匹配 (✿带花树开花)

    从前一个和谐的班级,所有人都是搞OI的.有 n 个是男生,有 0 个是女生.男生编号分别为 1,…,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽.每个人至多属于 ...

  7. URAL 1099 Work scheduling 一般图的最大匹配 带花树算法(模板)

    R - Work scheduling Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  8. kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

    二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...

  9. URAL 1099. Work Scheduling (一般图匹配带花树)

    1099. Work Scheduling Time limit: 0.5 secondMemory limit: 64 MB There is certain amount of night gua ...

随机推荐

  1. 用Python去除PDF水印

    今天介绍下用 Python 去除 PDF (图片)的水印.思路很简单,代码也很简洁. 首先来考虑 Python 如何去除图片的水印,然后再将思路复用到 PDF 上面. 这张图片是前几天整理<数据 ...

  2. 访问所有HTTPS网站显示连接不安全 (火狐浏览器)

    当 Firefox 连接到一个安全的网站时(网址最开始为"https://"),它必须确认该网站出具的证书有效且使用足够高的加密强度.如果证书无法通过验证,或加密强度过低,Fire ...

  3. hash 哈希表 缓存表

    系统初始hash表为空,当外部命令执行时,默认会从 PATH路径下寻找该命令,找到后会将这条命令的路径记录到 hash表中,当再次使用该命令时,shell解释器首先会查看hash 表,存在将执行之,如 ...

  4. Labview一个循环中放两个事件结构会导致前面板锁定的问题

    建议在同一个循环中,只放置一个事件结构.此时,当一个事件发生时,事件结构将对事件进行处理,然后继续循环,事件结构再等待下一个事件发生. 如在同一个循环中放置两个事件结构,只有在两个事件结构都处理了事件 ...

  5. 【高并发】深入解析Callable接口

    大家好,我是冰河~~ 本文纯干货,从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小. 1.Callable接口介绍 Callable接口是J ...

  6. Java第三天【变量、常量、数据类型】

    学习Java第三天!加油!请帖友看看有和不足的地方,和在下说一下,谢谢! 变量 变量(variable): 1.变量的本质就是代表"可操作的存储空间",空间位置是确定的,蛋里面放置 ...

  7. 『学了就忘』Linux基础命令 — 31、grep命令和通配符

    目录 1.grep命令介绍 2.find命令和grep命令的区别(重点) (1)find命令 (2)grep命令 3.通配符与正则表达式的区别 (1)通配符: (2)正则表达式: 1.grep命令介绍 ...

  8. 前端调试工具DevTools处理网络请求

    DevTools处理网络请求 位置:network 1.是否启用网络处理功能 2.清除历史 3.过滤器,自定义筛选 4.是否保留先前的历史,因为每次刷新会删除历史重新加载,选中后新老请求都在可做对比 ...

  9. 谷粒 | 10 | 阿里云OSS存储对象服务

    阿里云OSS对象存储服务 准备工作 1.在service模块新建子模块service_oss 2.引入pom.xml文件中引入oss服务依赖 <dependencies> <!--a ...

  10. dart系列之:在dart中使用packages

    目录 简介 pubspec.yaml get packages 使用packages 升级依赖 总结 简介 java中使用jar包来封装有用的功能,然后将其分发到maven仓库中,供其他人使用.同样的 ...