KM算法【带权二分图完美匹配】
先orz litble——KM算法
为什么要用KM算法##
因为有的题丧心病狂卡费用流
KM算法相比于费用流来说,具有更高的效率。
算法流程##
我们给每一个点设一个期望值【可行顶标】
对于左边的点来说,就是期望能匹配到多大权值的右边的点
对于右边的点来说,就是期望能在左边的点的期望之上还能产生多少贡献
两个点能匹配,当且仅当它们的期望值之和为这条边的权值
一开始初始化所有左点的期望是其出边的最大值,因为最理想情况下当然是每个点都匹配自己能匹配最大的那个
右点期望为0
然后我们逐个匹配,当一个点匹配失败时,所有左点的期望就过高了
我们从右点未匹配的点中找到离被匹配相差的期望最小的点,所有此次匹配涉及的左点减去这个期望值【使得能匹配的点多出了一个】,然后其匹配的右点要加上这个期望值【因为还要保证已匹配的点仍然能被匹配】
然后继续尝试匹配
直至所有点匹配完
板子:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 405,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int w[maxn][maxn],expa[maxn],expb[maxn],visa[maxn],visb[maxn],cp[maxn],dl[maxn];
int n;
bool dfs(int u){
visa[u] = true;
REP(i,n) if (!visb[i]){
int kl = expa[u] + expb[i] - w[u][i];
if (kl == 0){
visb[i] = true;
if (!cp[i] || dfs(cp[i])){
cp[i] = u; return true;
}
}
else dl[i] = min(dl[i],kl);
}
return false;
}
int solve(){
REP(i,n) expa[i] = expb[i] = cp[i] = 0;
REP(i,n) REP(j,n) expa[i] = max(expa[i],w[i][j]);
REP(i,n){
REP(j,n) dl[j] = INF;
while (true){
REP(j,n) visa[j] = false,visb[j] = false;
if (dfs(i)) break;
int kl = INF;
REP(j,n) if (!visb[j]) kl = min(kl,dl[j]);
REP(j,n){
if (visa[j]) expa[j] -= kl;
if (visb[j]) expb[j] += kl;
else dl[j] -= kl;
}
}
}
int re = 0;
REP(i,n) re += w[cp[i]][i];
return re;
}
int main(){
n = read();
REP(i,n) REP(j,n) w[i][j] = read();
printf("%d\n",solve());
return 0;
}
KM算法【带权二分图完美匹配】的更多相关文章
- KM算法 带权二分匹配 O(n^3)
#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #inclu ...
- POJ 2195 Going Home (带权二分图匹配)
POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...
- KM(Kuhn-Munkres)算法求带权二分图的最佳匹配
KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...
- 运动员最佳匹配问题 KM算法:带权二分图匹配
题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...
- Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)
Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...
- 费用流模板(带权二分图匹配)——hdu1533
/* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 1000 ...
- POJ 2195 Going Home | 带权二分图匹配
给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...
- UVALive 4043 Ants(二分图完美匹配)
题意:每个蚁群有自己的食物源(苹果树),已知蚂蚁靠气味辨别行进方向,所以蚁群之间的行动轨迹不能重叠.现在给出坐标系中n个蚁群和n棵果树的坐标,两两配对,实现以上要求.输出的第 i 行表示第 i 个蚁群 ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
随机推荐
- 解决wget下载https时报错 --no-check-certificate (不检查证书)
如果使用 wget下载https开头的网址域名 时报错,你需要加上 --no-check-certificate (不检查证书)选项 例如: wget https://pypi.python.org/ ...
- CYUSB
/*Summary The application cydesc is used to open the device with cypress GUID and get the device des ...
- 1.redis 安装
1.https://redis.io/download. 2. $ wget http://download.redis.io/releases/redis-3.2.9.tar.gz $ .tar.g ...
- sqlldr将txt导入oracle数据库
注意事项: 1.userid 和 control关键字不要缺少: 2.注意数据库格式:test/test@数据库IP:1521/Oracle8,最后一个是tnsnames中的service_name, ...
- 初尝微信小程序2-Swiper组件、导航栏标题配置
swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...
- 抽屉head部分,hover应用,鼠标放上变色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mysql中如何不重复插入,mysql 重复的不插入,mysql唯一的插入
INSERT INTO new_schedules_spider_shipsname ( ID,SCAC,VESSEL,VOYAGE,SERVICE_NAME,MD5 ) SELECT NULL,%s ...
- 第三篇:彻底解决ssh.invoke_shell() 返回的中文问题
接上一篇,前两篇解决中文的问题主要是在字符集上做的手脚,即将中文转成英文,但是有一种情况我们都来不及做转换,即登录时服务器直接返回了中文内容: 此时程序报了如下错误,其实还是字符集问题: 为此:我们可 ...
- k8s的pv和pvc简述
pvc:资源需要指定:1.accessMode:访问模型:对象列表: ReadWriteOnce – the volume can be mounted as read-write by a s ...
- 用scala的actor并发编程写一个单机版的WorldCount
前言:最近一段时间比较忙,也是比较懒了吧,好长时间没写博客了,新的一年到来,给自己一个小目标,博客坚持写下去,分享一下这历程!废话不多说,开始正题咯(希望大家喜欢!) 首先这算是一个scala程序的入 ...