P6577 【模板】二分图最大权完美匹配 (KM)

news/2024/9/22 23:18:01

$\quad $ 初看就发现不对劲了,模板紫题,一看就不简单,就交了个裸\(KM\),哎,果然\(T\)了。

$\quad $ 然后就是大力卡常(当然\(O(n^4)\))的复杂度不是卡常能解决的。遂看题解,发现一个据说\(O(n^3)\)的复杂度的\(KM\),也是非常抽象。
具体解释详见 https://www.luogu.com.cn/article/ip2m1gut

$\quad $ 当我还在研究题解的时候\(luobutianle\)直接就是溜过来跟我说倒着遍历可以起飞。我当时就是蒙,他就直接让我试了试,也是确实起飞了。

$\quad $ 大抵是造数据的人想卡\(KM\),认为人们都是正着遍历,就正着卡了。

献上我的大力卡常代码(当然过了)

点击查看代码
  #include<bits/stdc++.h>using namespace std;#define int long longconst int N=550,M=250500;int match[N],slack[N],a[N],b[N],w[N][N],n,m,vis[N],rnd;int r(){int ans=0;bool f=0;char ch=getchar();while(ch<'0' || ch>'9'){if(ch=='-')f=1;ch=getchar();}while(ch>='0' && ch<='9'){ans=(ans<<1)+(ans<<3)+(ch^48);ch=getchar();}return f?~ans+1:ans;}bool dfs(int x){for(int i=1;i<=n;i=-~i){if(vis[i]^rnd){if(!((a[x]+b[i])^w[x][i])){vis[i]=rnd;if(!match[i]||dfs(match[i])){match[i]=x;return true;}}else slack[i]=min(slack[i],a[x]+b[i]-w[x][i]);}}return false;}void write(long long n){if(n>9)write(n/10);putchar(n%10+'0');}signed main(){freopen("1.in","r",stdin);n=r(),m=r();for(int i=0;i<=n;i=-~i){for(int j=0;j<=n;j=-~j){w[i][j]=-9999999999;}}for(int i=1;i<=m;i=-~i)w[r()][r()]=r();for(int i=0;i<=n;i=-~i)a[i]=-99999999999;for(int i=1;i<=n;i=-~i){for(int j=1;j<=n;j=-~j){a[i]=max(a[i],w[i][j]);}}for(int i=0;i<=n;i=-~i)slack[i]=99999999999;for(int i=n;i>=1;i--){while(1){rnd++;if(dfs(i))break;int d=1e18;for(int j=1;j<=n;j++)if(vis[j]^rnd)d=min(d,slack[j]),slack[j]=99999999999;for(int j=1;j<=n;j++)if(vis[j]==rnd)b[j]+=d,a[match[j]]-=d;a[i]-=d;}}int ans=0;for(int i=1;i<=n;i=-~i)ans+=a[i]+b[i];ans<0?putchar('-'),ans=-ans:0;write(ans);putchar('\n');for(int i=1;i<=n;i=-~i)write(match[i]),putchar(' ');return 0;}

还有优化代码:

点击查看代码
  #include<bits/stdc++.h>using namespace std;#define int long longconst int N=550,M=250500;int match[N],slack[N],a[N],b[N];int vis[N],rnd,pre[N];bool vx[N],vy[N];int matchy[N],matchx[N];int w[N][N],n,m;queue<int>q;long long r(){long long ans=0;bool f=0;char ch=getchar();while(ch<'0' || ch>'9'){if(ch=='-')f=1;ch=getchar();}while(ch>='0' && ch<='9'){ans=(ans<<1)+(ans<<3)+(ch^48);ch=getchar();}return f?~ans+1:ans;}void fl(int x){int t;while(x){t=matchx[pre[x]];matchx[pre[x]]=x;matchy[x]=pre[x];x=t;}return;}void dfs(int l){memset(vx,0,sizeof vx);memset(vy,0,sizeof vy);memset(slack,0x7f,sizeof slack);while(q.size())q.pop();q.push(l);while(1){while(q.size()){int x=q.front();q.pop();vx[x]=1;for(int i=1;i<=n;i++){if(vy[i]!=1){if(a[x]+b[i]-w[x][i]<slack[i]){slack[i]=a[x]+b[i]-w[x][i];pre[i]=x;if(!slack[i]){vy[i]=1;if(!matchy[i]){fl(i);return;}else q.push(matchy[i]);}}}}}int d=1e18;for(int i=1;i<=n;i++)if(vy[i]!=1)d=min(d,slack[i]);for(int i=1;i<=n;i++){if(vx[i]==1)a[i]-=d;if(vy[i]==1)b[i]+=d;else slack[i]-=d;}for(int i=1;i<=n;i++){if(vy[i]!=1){if(!slack[i]){vy[i]=1;if(!matchy[i]){fl(i);return;}else q.push(matchy[i]);}}} }}void wr(int x){if(x>9)wr(x/10);putchar(x%10+'0');}signed main(){n=r(),m=r();memset(w,0xcf,sizeof w);for(int i=1;i<=m;i++){w[r()][r()]=r();}memset(a,0xcf,sizeof a);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i]=max(a[i],w[i][j]);for(int i=1;i<=n;i++)dfs(i);int ans=0;for(int i=1;i<=n;i++)ans+=a[i]+b[i];ans<0?putchar('-'),ans=-ans:0;wr(ans);putchar('\n');for(int i=1;i<=n;i++)wr(matchy[i]),putchar(' ');return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/31350.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

传说中的运维门户设计

在IT服务管理这片广阔天地中,运维门户如同一位技艺高超的魔术师,轻轻一挥手,便将纷繁复杂的运维世界化繁为简,编织成一张便捷高效、触手可及的网络。它不仅是ITSM系统中不可或缺的一环,更是连接用户与技术世界的桥梁,让服务触达变得像呼吸一样自然。 运维门户,这个听起来…

中电金信:专题报告商业银行对公数字化转型体系架构及实践拆解

当今,数字化转型已然成为商业银行发展的关键动力,在这个数字时代,对公业务数字化转型更是势在必行。基于此,中电金信发布《商业银行对公数字化转型专题报告》(简称《报告》),针对对公数字化转型进行了专题研究。报告对主要商业银行对公数字化转型进行了深入的业务调研和…

「网络流浅谈」最大流的应用

讲解了最大流的多种模型,从二分图匹配到拆点技巧,带你参观最大流的神秘。二分图匹配 考虑如何将二分图匹配问题,转化为流网络。设置 \(1\) 个汇点和源点,从源点向二分图一侧的每一个点连边,从另一侧向汇点连边,边权均为 \(1\),二分图中的边也全部加入,权值设为 \(1\)。…

单元测试

实验项目名称:实验四 单元测试2一、 实验目的 1、 掌握单元测试技术,并按单元测试的要求设计测试用例。  2、 掌握一种单元测试工具的使用。 二、 实验内容 自行学习C#或python或C++的其中一种单元测试工具的使用,自选一段单元代码(不少于15行),进行测试。完成实验报告…

同一个函数/不同函数的接口关联

第一种:在同一个方法中接口关联,可以直接提取后引用第二种:在不同方法中,声明全局变量,提取后引用第三种:通过在conftest.py文件中定义一个夹具,在测试用例函数中使用这个夹具 # 定义一个登录成功后获取token的夹具 @pytest.fixture(scope="session") def log…

windows 安装Nginx服务

一、版本说明Nginx版本:1.26.0 二、下载Nginx下载地址:https://nginx.org/en/download.html选择一个版本,这里选择最新稳定版本下载后解压到一个目录,注意解压目录最好不要有中文、空格因为电脑只有一个C盘所以地址在C盘,可以选择自己习惯的安装位置 三、下载winsw下载地…

统计力学中的概率论基础(一)

本文的主要内容是一些统计力学中的基础的概率论知识,如密度函数、分布函数和贝叶斯定理的一些基本概念,主要作为一个简单的知识内容记录和分享,后续还有更多的同系列文章。技术背景 统计力学是一门通过粒子的纯粹微观量来表示系统宏观量的学科,从统计分布出发,用无偏/有偏…

【转】十年技术进阶路,让我明白了三件要事(8000字长文)

前言【本文于2022-5-10日首发于ITPUB微信公众号平台】该篇文章是我第一次跟DTCC合作编写的,整篇文章大概8000字,可能花您15分钟阅读。我和DTCC的韩楠老师,共花7了天时间,每天把该文章打磨到晚上12点,在这非常感谢编辑老师的负责与付出。这篇也是我分享里为数不多“进阶”与…