题目链接

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. [HNOI2009]双递增序列(洛谷P4728)+小烈送菜(内部训练题)——奇妙的dp

    博主学习本题的经过嘤嘤嘤: 7.22 : 听学长讲(一知半解)--自己推(推不出来)--网上看题解--以为自己会了(网上题解是错的)--发现错误以后又自己推(没推出来)--给学长发邮件--得到正确解法 ...

  2. 2021.1.8 NKOJ 周赛总结

    意料之中..... A:nkoj 3900 AC小程序 http://oi.nks.edu.cn/zh/Problem/Details/3900 A题比较简单,单独分析一下A和C,其实就是一个斐波那契 ...

  3. 海思 core 电压动态调整

    http://www.eda365.com/forum.php?mod=viewthread&tid=108620&_dsign=5bee4dcb http://www.eda365. ...

  4. N 种仅仅使用 HTML/CSS 实现各类进度条的方式

    本文将介绍如何使用 HTML/CSS 创建各种基础进度条及花式进度条及其动画的方式,通过本文,你可能可以学会: 通过 HTML 标签 <meter> 创建进度条 通过 HTML 标签 &l ...

  5. 大数据中必须要掌握的 Flink SQL 详细剖析

    Flink SQL 是 Flink 实时计算为简化计算模型,降低用户使用实时计算门槛而设计的一套符合标准 SQL 语义的开发语言. 自 2015 年开始,阿里巴巴开始调研开源流计算引擎,最终决定基于 ...

  6. .NET 开源工作流: Slickflow流程引擎高级开发(九) -- 条件事件模式解释及应用

    前言:在流程流转过程中,有时候需要条件模式的支持,这样可以使得流程流转更加灵活多变.比如在业务变量满足一定的条件时,可以启动特定配置的流程(或者位于主流程内部的子流程).本文主要描述条件启动和条件中间 ...

  7. Mysql教程:(六)修改语句、、删除语句、字符查询like

    1.修改语句 update 表名 set  where 条件 mysql> update student set birth=1988,department='中文系' where id=901 ...

  8. Spark中资源调度和任务调度

    Spark比MR快的原因 1.Spark基于内存的计算 2.粗粒度资源调度 3.DAG有向无环图:可以根据宽窄依赖划分出可以并行计算的task 细粒度资源调度 MR是属于细粒度资源调度 优点:每个ta ...

  9. js中function (res) {}与(res) =>{}的区别

    这里是引用function (res) {} 中 打印this时是undefined 打印that时是有内容的                let that = this;              ...

  10. Python基础(迭代)

    # from collections import Iterable#collections模块的Iterable类型判断 # dict1 = {'a':111,'b':222,'c':333} # ...