训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y))
layout: post
title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y))
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- KM算法
- 训练指南
Golden Tiger Claw
题意
给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i]+col[j]恒成立。先输row,再输出col,再输出全部总和(总和应尽量小)。
思路
本题与匹配无关,但可以用KM算法解决。
KM算法中的顶标就是保持了Lx[i]+ly[j]>=g[i[j]再求最大权和匹配的,但这个最大权和并没有关系。我们可以将row[i]看成一个男的,col[i]看成一个女的,这样男女的总数就相等。
一般来说,Lx[i]或Ly[i]仅需要取该行/列中最大的那个数即可保证满足要求,但是这样太大了,可以通过调整来使得总和更小。而KM算法的过程就是一个调整的过程,每一对匹配的男女的那条边的权值就会满足等号 wi[j]=row[i]+col[j],至少需要一个来满足等号,这样才能保证row[i]+col[j]是达到最小的,即从j列看,col[j]满足条件且最小,从i行看,row[i]满足条件且最小。这刚好与KM算法求最大权和一样。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=5e2+50;
const ll inf=1e10;
const ll INF = 1000000000;
const double eps=1e-5;
int g[530][530]; ///存图
int nx,ny; /// 两边点数
bool visx[maxn],visy[maxn];
int slack[maxn];
int linker[maxn]; ///y中各点匹配状态
int lx[maxn],ly[maxn]; /// x,y中的点标号
bool dfs(int x){
visx[x]=true;
for(int y=0;y<ny;y++){
if(visy[y])continue;
int tmp=lx[x]+ly[y]-g[x][y];
if(tmp==0){
visy[y]=true;
if(linker[y]==-1||dfs(linker[y])){
linker[y]=x;return true;
}
}
else if(slack[y]>tmp)slack[y]=tmp;
}
return false;
}
int KM(){
memset(linker,-1,sizeof(linker));
memset(ly,0,sizeof(ly));
for(int i=0;i<nx;i++){
lx[i]=-inf;
for(int j=0;j<ny;j++){
if(g[i][j]>lx[i])lx[i]=g[i][j];
}
}
for(int x=0;x<nx;x++){
for(int i=0;i<ny;i++)slack[i]=inf;
while(true){
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
if(dfs(x))break;
int d=inf;
for(int i=0;i<ny;i++)
if(!visy[i]&&d>slack[i])d=slack[i];
for(int i=0;i<nx;i++)
if(visx[i])lx[i]-=d;
for(int i=0;i<ny;i++)
if(visy[i])ly[i]+=d;
else slack[i]-=d;
}
}
int res=0;
for(int i=0;i<ny;i++)
if(linker[i]!=-1)res+=g[linker[i]][i];
return res;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n;
while(cin>>n){
nx=ny=n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)cin>>g[i][j];
int ans=KM();
cout<<lx[0];
for(int i=1;i<n;i++)cout<<" "<<lx[i];cout<<endl;
cout<<ly[0];
for(int i=1;i<n;i++)cout<<" "<<ly[i];cout<<endl;
cout<<ans<<endl;
}
return 0;
}
训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y))的更多相关文章
- 训练指南 UVA - 11419(二分图最小覆盖数)
layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...
- 训练指南 UVA - 11354(最小生成树 + 倍增LCA)
layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true ma ...
- 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)
layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catal ...
- 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)
layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: ...
- 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)
layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...
- 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)
layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalo ...
- 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)
layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...
- 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth
A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...
- 【UVA 11383】 Golden Tiger Claw (KM算法副产物)
Omi, Raymondo, Clay and Kimiko are on new adventure- in search of new Shen Gong Wu. But EvilBoy Geni ...
随机推荐
- 雅礼集训 Day3 T3 w 解题报告
w 题目背景 \(\frac 14\)遇到了一道水题,双完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607^2\)眼就切掉了这题,嘲讽了\(\frac 14 ...
- 【BZOJ 2006】[NOI2010]超级钢琴 ST
我们先把所有最左端对应的最优右端入堆,eg: z 在[l,r](由题目给出的L,R决定)之间的最优解 y,然后出堆以后,再入堆z,y-1,z,y+1,那么我们只需要用st找最大前缀和就好了(ST是一 ...
- Codeforces 937.B Vile Grasshoppers
B. Vile Grasshoppers time limit per test 1 second memory limit per test 256 megabytes input standard ...
- [POJ2777] Count Color
\[Count Color\] Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 50865 Accepted: 15346 Des ...
- 解决mysql的日志文件过大的问题
https://www.2cto.com/database/201203/122984.html
- Qt 设置应用程序图标(windows)
Step 1: 创建 xxx.rc 文件. 将ico图标文件复制到项目根目录下.然后在该目录中新建xxx.rc文件,并输入一行代码: IDI_ICON1 ICON DISCARDABLE " ...
- offset--BUG
offsetWidth所获取的宽度并不是div的实际宽度,它包括div的width.border等. 在JS函数中,可以通过obj.style.width来获取div的实际宽度,但是这种方式style ...
- tomcat编码配置
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" ...
- PowerDesigner使用教程(转)
PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...
- JS向右弹出DIV,点击可向左隐藏。我用jquery可以从左下角像右上角隐藏,怎么从做向右隐藏呢?
弹出的DIV如果是绝对定位,就用right固定位子,如果不是就用float:right:Jquery中有个函数animate是自定义动画效果,$("#shou").click(fu ...