模板——二分图匹配KM
具体方法就不介绍了,详见 https://blog.csdn.net/sixdaycoder/article/details/47720471
主要讲一些注意点:
1:不直接将未匹配的y减小是因为要保证lx[i]+ly[j]>=w[i][j],证明详见上述博客
2:因为多组数据,所有数组都记得清零
3:dfs中坑了我20多次MLE……记得visx,visy数组都要更新
4:这种做法仅限于每一个点都能被匹配的情况,若不能都匹配就要用网络流
5:只有在值相等时才能赋值visy
二分图匹配模板题:(值得思考)
#include<bits/stdc++.h>
using namespace std;
int V,n,m,e;
vector<int> v[];
int vis[],match[]; int init()
{
memset(match,-,sizeof(match));
scanf("%d%d%d%d",&V,&n,&m,&e);
for(int i=;i<=e;i++)
{
int x,y;
scanf("%d%d",&x,&y); y+=n;
v[x].push_back(y);
}
} int dfs(int u)
{
for(int i=;i<(int)v[u].size();i++)
{
int p=v[u][i];
if(vis[p]) continue;
vis[p]=;
if(match[p]==-||dfs(match[p])==)
{
match[u]=p;
match[p]=u;
return ;
}
}
return ;
} int main()
{
int sum=;
init();
for(int i=;i<=n;i++)
{
if(match[i]==-)
{
memset(vis,,sizeof(vis));
if (dfs(i)) sum++;
}
}
printf("%d\n",min(V+,n+m-sum));
return ;
}
#include<cstdio>
#include<cstring>
using namespace std;
const int N=;
const int inf=0X3f3f3f; int w[N][N];
int n,ans=;
int lx[N],ly[N],match[N],slack[N];
bool visx[N],visy[N]; void init()
{
for(int i=;i<n;i++) visy[i]=;
for(int i=;i<n;i++) visx[i]=;
} bool dfs(int u)
{
int Delta;
visx[u]=;
for(int v=;v<n;++v)
{
if(visy[v]) continue;
Delta=lx[u]+ly[v]-w[u][v];
if(Delta==)
{
visy[v]=;
if(match[v]==-||dfs(match[v]))
{
match[v]=u;
return true;
}
}
else if(slack[v] > Delta)
slack[v] = Delta;
}
return false;
} void KM()
{
for(int x=;x<n;++x)
{
for(int y=;y<n;++y) slack[y]=inf;
while(true)
{
init();
if(dfs(x)) break;
int delta=inf;
for(int j=;j<n;++j) if(!visy[j]&&delta>slack[j]) delta=slack[j];
for(int i=;i<n;++i) if(visx[i]) lx[i]-=delta;
for(int j=;j<n;++j)
{
if(visy[j]) ly[j]+=delta;
else slack[j]-=delta;//important
}
}
}
} int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(match,-,sizeof(match));
memset(ly,,sizeof(ly));
for(int i=;i<n;++i) match[i]=-;
for(int i=;i<n;++i)
{
for(int j=;j<n;++j)
{
scanf("%d",&w[i][j]);
}
}
for(int i=;i<n;++i)
{
lx[i]=-inf;
for(int j=;j<n;j++) if(lx[i]<w[i][j]) lx[i]=w[i][j];
}
KM(); ans=;
for(int i=;i<n;++i)
{
if(match[i]!=-) ans+=w[match[i]][i];
}
printf("%d\n",ans);
}
return ;
}
模板——二分图匹配KM的更多相关文章
- 训练指南 UVALive - 4043(二分图匹配 + KM算法)
layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...
- 牛客多校第五场 E room 二分图匹配 KM算法模板
链接:https://www.nowcoder.com/acm/contest/143/E来源:牛客网 Nowcoder University has 4n students and n dormit ...
- hdu1853 Cyclic Tour (二分图匹配KM)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- [洛谷P3386] [模板] 二分图匹配 (匈牙利算法)
题目传送门 毒瘤出题人zzk出了个二分图匹配的题(18.10.04模拟赛T2),逼我来学二分图匹配. 网络流什么的llx讲完之后有点懵,还是匈牙利比较好理解(绿与被绿). 对于左边的点一个一个匹配,记 ...
- 二分图匹配--KM算法
Kuhn-Munkres算法 KM算法,求完备匹配下的最大权匹配,时间复杂度O(\(n^3\)) 所谓的完备匹配就是在二部图中,x点集中的所有点都有对应的匹配 且 y点集中所有的点都有对应的匹配 ,则 ...
- 【洛谷 p3386】模板-二分图匹配(图论)
题目:给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数. 解法:匈牙利算法.(以前我总是不记得......)实质上应该有贪心的思想,每次都尽量匹配,找到能和自己匹配的也尽量让它们匹配 ...
- Assignment HDU - 2853(二分图匹配 KM 新边旧边)
传送门: Assignment HDU - 2853 题意:题意直接那松神的题意了.给了你n个公司和m个任务,然后给你了每个公司处理每个任务的效率.然后他已经给你了每个公司的分配方案,让你求出最多能增 ...
- 运动员最佳匹配问题 KM算法:带权二分图匹配
题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...
- 二分图匹配之最佳匹配——KM算法
今天也大致学了下KM算法,用于求二分图匹配的最佳匹配. 何为最佳?我们能用匈牙利算法对二分图进行最大匹配,但匹配的方式不唯一,如果我们假设每条边有权值,那么一定会存在一个最大权值的匹配情况,但对于KM ...
随机推荐
- leetcode 题型 数据结构 解法 分类总结
第2章 线性表 2.1 数组 2.1.1 Remove Duplicates from Sorted Array 2.1.2 Remove Duplicates from Sorted Array I ...
- Neo4j和Elasticsearch
Neo4j和Elasticsearch Neo4j和Elasticsearch是一种让人眼前一亮的组合,为什么需要把搜索和图表结合起来呢?它们是如何使用的呢? 在无处不在的互联网搜索引擎的推动下,全文 ...
- 城市代码表mysql
只有代码: # ************************************************************ # Sequel Pro SQL dump # Version ...
- vue 报错:Cannot read property '__ob__' of undefined
我的原因:引入组件后未注册 <script> import ComFirst from "../../components/ComFirst.vue" import C ...
- 添加ASP.NET AJAX控件工具集到VS2010的方法
在VS2010中Ajax控件只有5个,其实还有很多支持AJAX特定功能的服务器控件,微软是将这些控件当作开放源代码项目.所以没有集成到VS2010中.这些AJAX控件被称为ASP.NET AJAX控件 ...
- PHP算法之分割平衡字符串
在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的. 给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串. 返回可以通过分割得到的平衡字符串的最大数量. 示例 1: 输入:s = ...
- CSIC_716_20191125【面向对象编程--类以及类的实例化】
面向对象编程:是一种编程思想 对象的定义:特征与功能的集合体 优点:可扩展性强 缺点:编程复杂度高,难度偏大 类的定义:一系列对象之间相同特征与技能的结合体 调用类的时候(实例化是时候),发生的事情: ...
- [JZOJ3691] 【CF414E】Mashmokh's Designed tree
题目 题目大意 给你一棵树,接下来对这棵树进行三种操作: 1.询问两点之间的距离. 2.让某个点变为它原来的第\(h\)个祖先的最后一个儿子. 3.求\(dfs\)序中最后一个深度为\(k\)的点. ...
- java 数组常见操作
1.遍历 依次访问数组中的每个元素 public class ArrayDemo04 { public static void main(String[] args) { int[] arr = { ...
- Windows ipconfig
用法: ipconfig [/allcompartments] [/? | /all | /renew [adapter] | / ...