HDU 1533:Going Home(KM算法求二分图最小权匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=1533
Going Home
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point. 
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
Sample Output
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 105
#define INF 0x3f3f3f
char maze[N][N];
int mp[N][N],match[N],lx[N],ly[N],visx[N],visy[N],slack[N];
int n,m,cnt;
struct node
{
int a,b;
}sa[N],sb[N];
//KM求二分图最小匹配模板:只需把权值都变成负的,再用KM算出最大权匹配,然后取反就是答案
//学习KM地址:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html
bool dfs(int x)
{
visx[x]=;
for(int y=;y<=cnt;y++){
if(visy[y]) continue;
int t=lx[x]+ly[y]-mp[x][y];
if(t==){
visy[y]=;
if(match[y]==-||dfs(match[y])){
match[y]=x;
return true;
}
}
else if(slack[y]>t) slack[y]=t;
}
return false;
} int KM()
{
memset(match,-,sizeof(match));
memset(lx,-INF,sizeof(lx));
memset(ly,,sizeof(ly));
for(int i=;i<=cnt;i++){
for(int j=;j<=cnt;j++){
if(mp[i][j]>lx[i]) lx[i]=mp[i][j];
}
}
for(int i=;i<=cnt;i++){
for(int y=;y<=cnt;y++)
slack[y]=INF;
while(){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(dfs(i)) break;
int d=INF;
for(int y=;y<=cnt;y++){
if(!visy[y]&&d>slack[y]) d=slack[y];
}
for(int x=;x<=cnt;x++){
if(visx[x]) lx[x]-=d;
}
for(int y=;y<=cnt;y++){
if(visy[y]) ly[y]+=d;
else slack[y]-=d;
}
}
}
int res=;
for(int i=;i<=cnt;i++){
if(match[i]>-) res+=mp[match[i]][i];
}
return res;
} int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
if(n+m==) break;
for(int i=;i<=n;i++){
scanf("%s",maze[i]+);
}
int cnt1=,cnt2=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(maze[i][j]=='m'){
sa[++cnt1].a=i;
sa[cnt1].b=j;
}
if(maze[i][j]=='H'){
sb[++cnt2].a=i;
sb[cnt2].b=j;
}
}
}
cnt=cnt1;
for(int i=;i<=cnt1;i++){
for(int j=;j<=cnt2;j++){
mp[i][j]=abs(sa[i].a-sb[j].a)+abs(sa[i].b-sb[j].b);
mp[i][j]=-mp[i][j];
}
}
printf("%d\n",-KM());
}
return ;
}
HDU 1533:Going Home(KM算法求二分图最小权匹配)的更多相关文章
- [ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4158 Accepted: 1777 Descr ...
- HDU 1533 二分图最小权匹配 Going Home
带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. #include <iostream> #include <cst ...
- POJ 2195 Going Home 【二分图最小权值匹配】
传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- KM算法(二分图的最佳完美匹配)
KM算法大概过程: (1)初始化Lx数组为该boy的一条权值最大的出边.初始化Ly数组为 0. (2)对于每个boy,用DFS为其找到一个girl对象,顺路记录下S和T集,并更新每个girl的slac ...
- poj 3565 uva 1411 Ants KM算法求最小权
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- poj3565 Ants km算法求最小权完美匹配,浮点权值
/** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...
随机推荐
- 查看安卓APK源码破解
原文:查看安卓APK源码破解 工具准备: <1>.android4me的AXMLPrinter2工具 <2>dex2jar <3>jd-gui 工具下载:http: ...
- 简洁的导出 datatable到excel,不用组件
简洁的导出 datatable到excel var lines = new List<string>(); string[] columnNames = dataTable.Columns ...
- 深入理解Amazon Alexa Skill(一)
语音助手(Virtual Personal Assistants, VPA)是物联网智能家居中很火的一个领域,用户可以通过语言作为入口来控制家里各种各样的设备,而亚马逊的Alexa(echo,echo ...
- C#基础加强篇—委托、Lambda表达式和事件(下)
3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的 ...
- murmurhash2算法 和 DJB Hash算法是目前最流行的hash算法
murmurhash2算法 和 DJB Hash算法是目前最流行的hash算法 1.DJB HASH算法 1 2 3 4 5 6 7 8 9 10 11 /* the famous DJB Hash ...
- C#破解access数据库密码方法
原文:C#破解access数据库密码方法 using System; using System.Collections.Generic; using System.IO; using System.L ...
- 零元学Expression Blend 4 - Chapter 6 如何置入Photoshop档案以及入门动画设计
原文:零元学Expression Blend 4 - Chapter 6 如何置入Photoshop档案以及入门动画设计 本章将教大家如何把Photoshop档案置入Expression Blend ...
- UWP中的消息提示框(一)
不管什么平台,应用内难免会出现一些消息提示框,下面就来聊聊我在UWP里用到的消息提示框. 弹窗也可按是否需要用户操作促发一些逻辑进行分为两大类. 不需要用户干涉的一类: MessageDialog:操 ...
- Easy Compression Library(代替TFileStream, TMemoryStream and TStream)
Easy Compression Library is a very easy-to-use replacement of TFileStream, TMemoryStream and other T ...
- new和delete必须成对出现吗?【网上集合贴+个人总结】
new和delete必须成对出现吗?[网上集合贴+个人总结] 1.从内存泄露与否的角度考虑 new 和 delete不一定要成对出現.理论上是這樣的.但是从习惯上來說,new delete成對出現是一 ...