Going Home

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5504    Accepted Submission(s): 2890
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

 

Source


/**
题目:hdu1533 Going Home
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533
题意:n个人回到n个房子,每个房子只能住一个人。求最少花费。
思路:
构造一个源点,到达所有的人,cap = 1, cost = 0;
构造一个汇点,所有的房子到汇点,cap = 1, cost = 0;
所有的人到所有的房子,cap = 1, cost = 人到房子的最短距离。
然后最小费用最大流算法。
*/
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int N = ;
struct Edge{
int from, to, cap, flow, cost;
Edge(int u,int v,int c,int f,int cost):from(u),to(v),cap(c),flow(f),cost(cost){}
};
struct MCMF
{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[N];
int inq[N];
int d[N];
int p[N];
int a[N]; void init(int n)
{
this->n = n;
for(int i = ; i <= n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost){
edges.push_back((Edge){from,to,cap,,cost});
edges.push_back((Edge){to,from,,,-cost});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BellmanFord(int s,int t,int &flow,int &cost){
for(int i = ; i <= n; i++) d[i] = INF;
memset(inq, , sizeof inq);
d[s] = ; inq[s] = ; p[s] = ; a[s] = INF; queue<int> Q;
Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = ;
for(int i = ; i < G[u].size(); i++){
Edge& e = edges[G[u][i]];
if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
d[e.to] = d[u]+e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u],e.cap-e.flow);
if(!inq[e.to]){ Q.push(e.to); inq[e.to] = ;}
}
}
}
if(d[t]==INF) return false;
flow += a[t];
cost += d[t]*a[t];
int u = t;
while(u!=s){
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
u = edges[p[u]].from;
}
return true;
}
int Mincost(int s,int t)
{
int flow = , cost = ;
while(BellmanFord(s,t,flow,cost)) ;
return cost;
}
int dis(int x,int y,int xx,int yy)
{
return abs(x-xx)+abs(y-yy);
}
};
char s[N][N];
typedef pair<int,int> P;
vector<P> man;
vector<P> hou;
int main()
{
int n, m;
while(scanf("%d%d",&n,&m)==)
{
if(n==&&m==) break;
man.clear();
hou.clear();
for(int i = ; i < n; i++){
scanf("%s",s[i]);
for(int j = ; j < m; j++){
if(s[i][j]=='m'){
man.push_back(P(i,j));
}
if(s[i][j]=='H'){
hou.push_back(P(i,j));
}
}
}
MCMF mcmf;
mcmf.s = ;
mcmf.t = man.size()*+;
mcmf.init(mcmf.t);
for(int i = ; i < man.size(); i++){/// s->man
mcmf.AddEdge(mcmf.s,i+,,);
}
for(int i = ; i < hou.size(); i++){/// hou->t
mcmf.AddEdge(man.size()+i+,mcmf.t,,);
}
///man->hou
for(int i = ; i < man.size(); i++){
for(int j = ; j < hou.size(); j++){
int from, to, cap, cost;
from = i+;
to = man.size()+j+;
cap = ;
cost = mcmf.dis(man[i].first,man[i].second,hou[j].first,hou[j].second);
mcmf.AddEdge(from,to,cap,cost);
}
}
printf("%d\n",mcmf.Mincost(mcmf.s,mcmf.t));
}
return ;
}

hdu1533 Going Home 最小费用最大流 构造源点和汇点的更多相关文章

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

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

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

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

  3. HIT2739 The Chinese Postman Problem(最小费用最大流)

    题目大概说给一张有向图,要从0点出发返回0点且每条边至少都要走过一次,求走的最短路程. 经典的CPP问题,解法就是加边构造出欧拉回路,一个有向图存在欧拉回路的充分必要条件是基图连通且所有点入度等于出度 ...

  4. BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模

    本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...

  5. 最小费用最大流 POJ2195-Going Home

    网络流相关知识参考: http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 出处:優YoU http://blog.csdn. ...

  6. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

    题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...

  7. POJ 2195 Going Home(最小费用最大流)

    http://poj.org/problem?id=2195 题意 :  N*M的点阵中,有N个人,N个房子.让x个人走到这x个房子中,只能上下左右走,每个人每走一步就花1美元,问当所有的人都归位了之 ...

  8. [BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘

    [Problem Description] 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队 ...

  9. POJ 3422 Kaka&#39;s Matrix Travels (最小费用最大流)

    POJ 3422 Kaka's Matrix Travels 链接:http://poj.org/problem? id=3422 题意:有一个N*N的方格,每一个方格里面有一个数字.如今卡卡要从左上 ...

随机推荐

  1. httpclient4.3访问https

    1.创建一个访问https的工具类 package org.aaa.tool;import java.io.File; import java.io.IOException; import java. ...

  2. SweetAlert和MBProgressHUD冲突的解决办法

    解决方法 :   UIView *view = [UIApplication sharedApplication].keyWindow;             NSLog(@" -- &g ...

  3. pytimechart使用

    参考网站:http://pythonhosted.org/pytimechart/userguide.html 安装: sudo apt-get install python-chaco python ...

  4. iOS开发笔记_5.线程,HTTP请求,定时器

    说起线程,不会陌生了,操作系统课程里已经详细介绍了这个东东,这里就不解释了,想要了解的问问百度或者翻翻书. 线程的创建 总结了昨天的学习,有下面几种创建的方式. //第一种 NSThread *t = ...

  5. expdp impdp 数据库导入导出命令详解

    一.创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建.create directory dpdata1 as 'd:\test\dump'; 二.查看管理理员目录(同时 ...

  6. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.9. 配置用户等效性(可选项)

    2.9.配置用户等效性(可选项) Oracle 11g r2 ssh也可以在安装过程中配置. 2.9.1. grid用户等效性 1.以下均以grid用户执行: 在两个节点的grid主目录分别创建.ss ...

  7. Nginx 报错413 Request Entity Too Large 上传文件过大

    1.进入Nginx安装路径下的conf文件夹中(我的路径是:/usr/local/nginx/conf) 2.打开nginx.conf,在http大括号中第一行加语句:client_max_body_ ...

  8. 倍福TwinCAT(贝福Beckhoff)应用教程12.2 TwinCAT控制松下伺服 NC初步

    在前面我们已经学会了使用贝福自带的调试软件完成试运行,接下来是使用TWINCAT PLC实现这个功能,右击PLC添加一个PLC项目   在VISUs上右击添加一个HMI人机界面   目前PLC程序和人 ...

  9. 【微信转载】Google是如何做测试的

    就 目前的软件公司而言,Google无疑是在开放和创新力方面做得最好的.而如何支撑Google这种快速地扩张的研发能力以及迭代速度,并且产品质量总是 一如以往的能给人们很棒的用户体验?这是一个值得我们 ...

  10. Centos系统信息及日志

    1.确认内核版本: #uname -r #uname -a 2.确认发行版本: #cat /etc/redhat-release 3.查看系统载入的模块: #lsmod | grep XXX 载入一个 ...