Going Home
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 22088   Accepted: 11155

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

  1. 2 2
  2. .m
  3. H.
  4. 5 5
  5. HH..m
  6. .....
  7. .....
  8. .....
  9. mm..H
  10. 7 8
  11. ...H....
  12. ...H....
  13. ...H....
  14. mmmHmmmm
  15. ...H....
  16. ...H....
  17. ...H....
  18. 0 0

Sample Output

  1. 2
  2. 10
  3. 28

Source


每个人和每个房子连边,二分图最大权匹配
用spfa费用流求解(或者KM)
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. typedef long long ll;
  8. const int N=,M=1e6+,INF=1e9;
  9. int read(){
  10. char c=getchar();int x=,f=;
  11. while(c<''||c>''){if(c=='-')f=-; c=getchar();}
  12. while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
  13. return x*f;
  14. }
  15. int n,m,s,t,n1,n2;
  16. char ss[];
  17. struct data{
  18. int x,y;
  19. }a[N],b[N];
  20. inline int dis(data &a,data &b){return abs(a.x-b.x)+abs(a.y-b.y);}
  21.  
  22. struct edge{
  23. int v,ne,c,f,w;
  24. }e[M<<];
  25. int cnt,h[N];
  26. inline void ins(int u,int v,int c,int w){
  27. cnt++;
  28. e[cnt].v=v;e[cnt].c=c;e[cnt].f=;e[cnt].w=w;
  29. e[cnt].ne=h[u];h[u]=cnt;
  30. cnt++;
  31. e[cnt].v=u;e[cnt].c=;e[cnt].f=;e[cnt].w=-w;
  32. e[cnt].ne=h[v];h[v]=cnt;
  33. }
  34. void build(){
  35. cnt=;
  36. memset(h,,sizeof(h));
  37. s=;t=n1+n2+;
  38. for(int i=;i<=n1;i++)
  39. for(int j=;j<=n2;j++) ins(i,n1+j,,dis(a[i],b[j]));
  40. for(int i=;i<=n1;i++) ins(s,i,,);
  41. for(int i=;i<=n2;i++) ins(n1+i,t,,);
  42. }
  43. int d[N],q[N],head,tail,inq[N],pre[N],pos[N];
  44. inline void lop(int &x){if(x==N)x=;}
  45. bool spfa(){
  46. memset(d,,sizeof(d));
  47. memset(inq,,sizeof(inq));
  48. head=tail=;
  49. d[s]=;inq[s]=;q[tail++]=s;
  50. pre[t]=-;
  51. while(head!=tail){
  52. int u=q[head++];inq[u]=;lop(head);
  53. for(int i=h[u];i;i=e[i].ne){
  54. int v=e[i].v,w=e[i].w;
  55. if(d[v]>d[u]+w&&e[i].c>e[i].f){
  56. d[v]=d[u]+w;
  57. pre[v]=u;pos[v]=i;
  58. if(!inq[v])q[tail++]=v,inq[v]=,lop(tail);
  59. }
  60. }
  61. }
  62. return pre[t]!=-;
  63. }
  64. int mcmf(){
  65. int flow=,cost=;
  66. while(spfa()){
  67. int f=INF;
  68. for(int i=t;i!=s;i=pre[i]) f=min(f,e[pos[i]].c-e[pos[i]].f);
  69. flow+=f;cost+=d[t]*f;
  70. for(int i=t;i!=s;i=pre[i]){
  71. e[pos[i]].f+=f;
  72. e[((pos[i]-)^)+].f-=f;
  73. }
  74. }
  75. return cost;
  76. }
  77. int main(int argc, const char * argv[]){
  78. while(true){
  79. n1=n2=;
  80. n=read();m=read();
  81. if(n==&&m==) break;
  82. for(int i=;i<=n;i++){
  83. scanf("%s",ss+);
  84. for(int j=;j<=m;j++){
  85. if(ss[j]=='H') a[++n1]=(data){i,j};
  86. if(ss[j]=='m') b[++n2]=(data){i,j};
  87. }
  88. }
  89. build();
  90. printf("%d\n",mcmf());
  91. }
  92. }
 
 
 
 

POJ2195 Going Home[费用流|二分图最大权匹配]的更多相关文章

  1. 【BZOJ 3308】 3308: 九月的咖啡店 (费用流|二分图最大权匹配)

    3308: 九月的咖啡店 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 244  Solved: 86 Description 深绘里在九份开了一家咖 ...

  2. POJ2195 Going Home (最小费最大流||二分图最大权匹配) 2017-02-12 12:14 131人阅读 评论(0) 收藏

    Going Home Description On a grid map there are n little men and n houses. In each unit time, every l ...

  3. [hdu1533]二分图最大权匹配 || 最小费用最大流

    题意:给一个n*m的地图,'m'表示人,'H'表示房子,求所有人都回到房子所走的距离之和的最小值(距离为曼哈顿距离). 思路:比较明显的二分图最大权匹配模型,将每个人向房子连一条边,边权为曼哈顿距离的 ...

  4. 【bzoj3291】Alice与能源计划 模拟费用流+二分图最大匹配

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验. 为了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  5. @noi.ac - 507@ 二分图最大权匹配

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一天你学了一个能解决二分图最大权匹配的算法,你决定将这个算法应 ...

  6. Hdu2255 奔小康赚大钱(二分图最大权匹配KM算法)

    奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好 ...

  7. [ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)

    奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间 ...

  8. HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    ...

  9. 二分图最大权匹配——KM算法

    前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...

随机推荐

  1. Unity3D 5.x 交互功能 - 光线投射、碰撞设置

    1,光线投射碰撞:第一人称视线在预置范围内(如3米)和看到的物体发生碰撞 ① 检测光线投射碰撞的脚本添加在第一人称FPSController上 #pragma strict private var c ...

  2. 最好的Angular2表格控件

    现在市面上有大量的JavaScript数据表格控件,包括开源的第三方的和自产自销的.可以说Wijmo的Flexgrid是目前适应Angular 2的最好的表格控件. Angular 2数据表格基本要求 ...

  3. workman源代码阅读 - 使用信号处理器实现定时器

    <?php /** * SIGALRM信号处理器注册成功后,在什么情况下进程会收到该信号呢? * * 在Linux系统下,每个进程都有惟一的一个定时器,该定时器提供了以秒为单位的定时功能.在定时 ...

  4. 【Java每日一题】20161220

    package Dec2016; public class Ques1220 { public static void main(String[] args) { Integer num1 = new ...

  5. linux 安装rz sz命令

    wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz tar zxvf lrzsz-0.12.20.tar.gz cd lrzsz-0.1 ...

  6. 从零开始学Python06作业思路:学生选课系统

    一,作业要求 选课系统: 管理员: 创建老师:姓名.性别.年龄.资产 创建课程:课程名称.上课时间.课时费.关联老师 学生:用户名.密码.性别.年龄.选课列表[].上课记录{课程1:[di,a,]} ...

  7. 企业管理咨询Interview Checklist

    企业管理咨询Interview Checklist 一. 企业战略 1. 您对公司所处行业的看法如何? 2. 请您介绍一下公司的发展历程,主要业务开展状况及核心竞争力.关键成功因素有哪些? 3. 在您 ...

  8. JdbcTemplate进行查询

    1.jdbcTemplate.queryForInt() 和 jdbcTemplate.queryForLong() 例如:下面使用queryForInt()方法传回user表中的记录数: jdbcT ...

  9. java web学习总结(十) -------------------HttpServletRequest对象

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  10. 基于SSH框架的学生公寓管理系统的质量属性

    系统名称:学生公寓管理系统 首先介绍一下学生公寓管理系统,在学生公寓管理方面,针对学生有关住宿信息问题进行管理,学生公寓管理系统主要包含了1)学生信息记录:包括学号.姓名.性别.院系.班级:2)住宿信 ...