P2764 最小路径覆盖问题

prologue

看见题解区好多神犇都是用 网络流 来做的,但是蒟蒻在刚学完 二部图 之后就来刷题了,对于这个题的路径输出有一个 比较新颖 的搞法,所以说就来写了这篇题解。

analysis

首先,我们为了将它转换成为一个 二部图,我们需要对它进行拆点操作(其实最后我跑起来并没有拆点),然后对它进行分析。

(下面左部为出度的点,右部为入度的点)

这个时候,原图中的每条路径转化到新图中,每一个点都可以对应出来一个匹配。每一条路径的 终点 都会对应到 左部 一个 非匹配点。这个时候我们要求 最小路径覆盖,就等价于 左部非匹配点最少,即这个图的 最大匹配。我们求最大匹配可以使用 匈牙利算法(之后输出合法路径需要)。

记我们的 最大匹配m最小路径覆盖 就为 nm

之后我们再考虑怎么去输出合法路径。

我们观察我们上面匈牙利算法中的 match 数组,每一个 右部 点的 match 都会对应到我们一个新图中的一个 左部点,我们再将这个点放到 右部点 来看,会由它的 match 对应一个 左部点。重复以上过程,直到我们无法再匹配 左部点

这个不断往回匹配的过程我们可以用 递归 来解决,边界条件就是匹配到 0。我们只需要在跑这个递归的过程中用一个 vector 来记录路径就行。

code time

(我下面的这个 cnt 写的稀碎,我知道为啥,但是调不出来,除了占空间之外好像没啥缺点,还能当作一个(虚假的)可持久化来看)

using namespace std; #define ll long long #define rl register ll #define x first #define y second typedef pair<ll, ll> pll; const ll N = 160; ll n, m; bool st[N], g[N][N]; ll cnt, pre_cnt; ll match[N]; pll pre[N]; vector<ll> path[N]; inline bool find(ll u) { for(rl i=1; i <= n; ++ i) if(g[u][i] && !st[i]) { st[i] = true; ll t = match[i]; if(!t || find(t)) { match[i] = u; return true; } } return false; } inline void get_path(ll u) { path[cnt].push_back(u); st[u] = 1; if(!pre[u].y) { cnt ++ ; return ;} get_path(pre[u].y); } inline bool cmp(pll a, pll b) { return a.y > b.y; } int main() { cin >> n >> m; for(rl i=1; i <= m; ++ i) { ll a, b; cin >> a >> b; g[a][b] = true; } ll res = 0; for(rl i=1; i <= n; ++ i) { memset(st, 0, sizeof st); if(find(i)) res ++ ; } memset(st, 0, sizeof st); for(rl i=1; i <= n; ++ i) pre[i] = {i, match[i]}; for(rl i=n; i; -- i) if(!st[i] && pre[i].x) get_path(pre[i].x); for(rl i=cnt - n + res; i < cnt; ++ i) { for(rl j : path[i]) cout << j << " "; cout << endl; } cout << n - res << endl; return 0; }

__EOF__

本文作者carp
本文链接https://www.cnblogs.com/carp-oier/p/17731169.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   carp_oier  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示