Going Home
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 17955   Accepted: 9145

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 <queue>
#include <algorithm>
#include <assert.h>
#include <cstring>
using namespace std;
const int inf=0x7fffffff;
int n,m; char maz[][];
int man[][];
int house[][];
int hlen,mlen; const int sups=;
const int supt=; int cost[][];
int f[][];
int e[][];
int len[]; int d[];
int pre[];
bool vis[]; queue<int >que; int main(){
while(scanf("%d%d",&n,&m)==&&n&&m){
input:
hlen=mlen=;
gets(maz[]);
for(int i=;i<n;i++){
gets(maz[i]);
}
for(int i=;i<n;i++){
for(int j=;j<m;j++){
if(maz[i][j]=='m'){
man[mlen][]=i;man[mlen++][]=j;
}
else if(maz[i][j]=='H'){
house[hlen][]=i;house[hlen++][]=j;
}
}
} memset(f,,sizeof(f));
memset(cost,,sizeof(cost));
fill(len,len+mlen,hlen+);fill(len+mlen,len+mlen+hlen,mlen+);len[sups]=mlen;len[supt]=hlen;
bulidedge:
for(int i=;i<mlen;i++){
f[sups][i]=;
e[sups][i]=i;
e[i][]=sups;
for(int j=;j<hlen;j++){
e[i][j+]=j+mlen;
e[j+mlen][i+]=i;
f[i][j+mlen]=;
cost[i][j+mlen]=abs(man[i][]-house[j][])+abs(man[i][]-house[j][]);
cost[j+mlen][i]=-cost[i][j+mlen];
}
}
for(int j=;j<hlen;j++){
e[supt][j]=j+mlen;
e[j+mlen][]=supt;
f[j+mlen][supt]=;
} mincostflow:
int ans=;
int flow=mlen;
while(flow>){
fill(d,d+,inf);
d[sups]=;
que.push(sups);
while(!que.empty()){
int fr=que.front();que.pop();
vis[fr]=false;
for(int i=;i<len[fr];i++){
int to=e[fr][i];
if(f[fr][to]>&&d[to]>d[fr]+cost[fr][to]){
d[to]=d[fr]+cost[fr][to];
pre[to]=fr;
if(!vis[to]){
que.push(to);
vis[to]=true;
}
}
}
} assert(d[supt]!=inf); int sub=flow;
for(int i=supt;i!=sups;i=pre[i]){
sub=min(flow,f[pre[i]][i]);
}
flow-=sub;
ans+=sub*d[supt];
for(int i=supt;i!=sups;i=pre[i]){
f[pre[i]][i]-=sub;
f[i][pre[i]]+=sub;
} }
printf("%d\n",ans);
}
return ;
}

POJ 2195 Going Home 最小费用流 难度:1的更多相关文章

  1. POJ 2195 Going Home 最小费用流 裸题

    给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数. 现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人. 每个人可以向4个方向移动,每移动一步需要1$,问所有 ...

  2. POJ 2195 Going Home 最小费用流

    POJ2195 裸的最小费用流,当然也可以用KM算法解决,但是比较难写. 注意反向边的距离为正向边的相反数(因此要用SPFA) #include<iostream> #include< ...

  3. POJ 2516 Minimum Cost 最小费用流 难度:1

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13511   Accepted: 4628 Des ...

  4. POJ 2195 Going Home 最小费用最大流 尼玛,心累

    D - Going Home Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  5. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  6. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  7. POJ 2195 Going Home (带权二分图匹配)

    POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...

  8. poj 2195 Going Home(最小费最大流)

    poj 2195 Going Home Description On a grid map there are n little men and n houses. In each unit time ...

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

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

随机推荐

  1. Python3基础 print \n换行

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  2. ubuntu下交叉编译imagemagick

    环境:ubuntu16.04 交叉编译器版本号:4.8.3 在编译之前要编译以下其依赖的软件或库:freetype,libpng,libxml2,libtiff,libjpeg,zlib,graphv ...

  3. 【入门详解】MyBatis入门基础详解

    什么是mybatis? MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XM ...

  4. 第四章 消息摘要算法--SHA

    注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 4.1.SHA 原理:消息摘要长度(可以定量为加密后的字符串的长度)越长,安全性越高 ...

  5. 安卓开发 Activity入门

    生命周期 Activity包含5种状态,涉及7种方法 1. 启动状态 2. 运行状态 *** 即使内存不足,Android先销毁栈底的Activity,来确保当前Activity正常运行 3. 暂停状 ...

  6. Ubuntu 14.04 下 OF-Config安装

    参考: Github of-config configure.ac - configure file issue OF-Config安装 1.安装OvS v2.3.1: Releases $ tar ...

  7. Python实现自平衡二叉树AVL

    # -*- coding: utf-8 -*- from enum import Enum #参考http://blog.csdn.net/niteip/article/details/1184069 ...

  8. shell 布尔运算符

    布尔运算符 下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20: 运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true. [ ! false ...

  9. JSON序列化反序列化

    JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的文本格式,可以很容易在 ...

  10. JavaMai——邮箱验证用户注册

    这篇文章简单的模拟了网上利用邮箱激活用户注册这样的一个功能 1. 呈现给用户的注册界面:(为了简单起见,就剩下两个输入域,邮箱和昵称) <%@ page language="java& ...