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. EntityFrameworkCore 一对一 && 一对多 && 多对多配置

    基本数据结构 表设计如下: 入学记录 public class AdmissionRecord { [Key] public long Id { get; set; } public DateTime ...

  2. Angular语法(一)——展示数据

    双花括号{{}} 展示数据 title = 'Tour of Heroes'; myHero = 'Windstorm'; <h1>{{title}}</h1> <h2& ...

  3. WPF编游戏系列 之八 银行界面及金额校验

    原文:WPF编游戏系列 之八 银行界面及金额校验        在前面<WPF编游戏系列 之四 用户控件>一文中通过用户控件创建了"My Shop"中物品列表框.本篇继 ...

  4. XF 绝对布局

    using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation (XamlCompila ...

  5. WPF Button控件模板

     <Window x:Class="ControlTemplateDemo.MainWindow"        xmlns="http://schemas.m ...

  6. 【全面解禁!真正的Expression Blend实战开发技巧】序章

    原文:[全面解禁!真正的Expression Blend实战开发技巧]序章 从silverlight2开始我也和大家一样一直在跟随微软的脚步,从sl2~sl4一步一步过来,总结了不少心得体会.由于各种 ...

  7. Oracle报错:不是GROUP BY 表达式

    报错:不是GROUP BY 表达式 实例:select sum(hwjz),rq from JcChargeInfo where 1=1  group by rq order by jcchargec ...

  8. 写给非专业人士看的 *** 简介(同时也解释了GFW )

    写给非专业人士看的 *** 简介 这个文章来源于一个朋友在***的过程中,搞不清楚 *** 的配置问题,在这里我想按照我对 *** 的理解简单梳理一下,以便一些非专业人士也能了解 long long ...

  9. C#实现判断图形文件格式的方法

    1. 通过文件的扩展名来判断.这种方法比较简单,但若是有人故意改下文件扩展名,这种方法就不起作用了. 2.通过C#自身提供的方法来进行判断(判断某种确定的图片类型). 示例如下: bool isJPG ...

  10. OSGI资料

    http://osgi.codeplex.com/ http://www.iopenworks.com/