http://acm.hdu.edu.cn/showproblem.php?pid=1533

Going Home

Problem Description
 
On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every step he moves, until he enters a house. The task is complicated with the restriction that each house can accommodate only one little man.

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.

 
Input
 
There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing the map. You may assume both N and M are between 2 and 100, inclusive. There will be the same number of 'H's and 'm's on the map; and there will be at most 100 houses. Input will terminate with 0 0 for N and M.
 
Output
 
For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay. 
 
Sample Input
 
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
 

Sample Output

2
10
28
 
 #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算法求二分图最小权匹配)的更多相关文章

  1. [ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  2. [ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Descr ...

  3. HDU 1533 二分图最小权匹配 Going Home

    带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. #include <iostream> #include <cst ...

  4. POJ 2195 Going Home 【二分图最小权值匹配】

    传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  5. UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design

    题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi  ...

  6. KM算法(二分图的最佳完美匹配)

    KM算法大概过程: (1)初始化Lx数组为该boy的一条权值最大的出边.初始化Ly数组为 0. (2)对于每个boy,用DFS为其找到一个girl对象,顺路记录下S和T集,并更新每个girl的slac ...

  7. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  8. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  9. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

随机推荐

  1. DevOps技术路线图

    来自roadmap.sh github地址 自己整理的百度脑图中文版

  2. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

  3. JS里脱离文档流

    <html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title&g ...

  4. TCP 的那些事儿(上,下)

    http://coolshell.cn/articles/11564.html http://coolshell.cn/articles/11609.html

  5. discuz电脑访问手机版域名怎么跳转到电脑版本

    用discuz论坛访问手机版本的域名不会自动跳转到电脑版本,而是会跳转到域名+misc.php?mod=mobile体验很不好.现提供修改方法:打开论坛根目录找到文件./source/class/di ...

  6. Spring 核心技术(1)

    接上篇:Spring 框架概述 version 5.1.8.RELEASE 这部分参考文档涵盖了 Spring Framework 所有绝对不可或缺的技术. 其中最重要的是 Spring Framew ...

  7. DateTime格式转换结果

    Console.WriteLine(string.Format("ToLongDateString:{0}", DateTime.Now.ToLongDateString())); ...

  8. Android零基础入门第38节:初识Adapter

    原文:Android零基础入门第38节:初识Adapter 在上一节一起了解了ListView的简单使用,那么本节继续来学习与ListView有着千丝万缕的Adapter. 一.了解MVC模式 在开始 ...

  9. .NET重思(二)接口和抽象类的取舍

    不得不说,接口和抽象类好像啊~两者都不可以实例化,并且未实现的部分都是由派生类实现的. 他们主要有这么个区别: (1)抽象类的派生类可以是派生类,换言之,抽象成员在派生类中不一定完全实现,而接口要求其 ...

  10. 瑞芯微RK3399宣布系统开源,进入百余种行业市场!

    集微网消息,2月24日瑞芯微官方突然宣布, Rockchip RK3399Linux系统开源!作为Rockchip旗舰级芯片,RK3399具有高性能.高扩展.全能型应用特性. 这一重磅消息立马刷爆朋友 ...