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 <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#define pi acos(-1.0)
#define eps 1e-6
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define bug printf("******\n")
#define mem(a,b) memset(a,b,sizeof(a))
#define fuck(x) cout<<"["<<x<<"]"<<endl
#define f(a) a*a
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define FIN freopen("DATA.txt","r",stdin)
#define lowbit(x) x&-x
#pragma comment (linker,"/STACK:102400000,102400000") using namespace std;
const int maxn = 1e5 + ;
typedef long long LL;
const int MX = ;
const int inf = 0x3f3f3f3f;
const int MXE = MX * MX * ;
struct MinCost_MaxFlow {
struct Edge {
int v, w, nxt;
int cost;
} E[MXE];
int head[MX], tot, level[MX], pre[MX], d[MX];
bool vis[MX];
void init() {
memset(head, -, sizeof(head));
tot = ;
}
void add(int u, int v, int w, int cost) {
E[tot].v = v;
E[tot].w = w;
E[tot].cost = cost;
E[tot].nxt = head[u];
head[u] = tot++;
E[tot].v = u;
E[tot].w = ;
E[tot].cost = -cost;
E[tot].nxt = head[v];
head[v] = tot++;
}
bool spfa(int s, int t) {
memset(vis, , sizeof(vis));
memset(d, 0x3f, sizeof(d));
memset(pre, -, sizeof(pre));
queue<int>q;
q.push(s);
d[s] = ;
vis[s] = ;
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = ;
for (int i = head[u]; ~i; i = E[i].nxt) {
int w = E[i].w, v = E[i].v, cost = E[i].cost;
if (w > && d[v] > d[u] + cost) {
d[v] = d[u] + cost;
pre[v] = i;
if (!vis[v]) {
q.push(v);
vis[v] = ;
}
}
}
}
//如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
//if (d[t] > 0) return false;
return pre[t] != -;
}
int solve(int s, int t, int &cost) {
int flow = ;
cost = ;
while (spfa(s, t)) {
int minFlow = inf;
for (int i = pre[t]; ~i; i = pre[E[i ^ ].v])
minFlow = min(minFlow, E[i].w);
for (int i = pre[t]; ~i; i = pre[E[i ^ ].v]) {
cost += minFlow * E[i].cost;
E[i].w -= minFlow;
E[i ^ ].w += minFlow;
}
flow += minFlow;
}
return flow;
}
} F;
int n, m;
struct Point {
int x, y;
Point (int x, int y): x(x), y(y) {}
};
int cal(Point a, Point b) {
return abs(a.x - b.x) + abs(a.y - b.y);
}
char tu[][];
vector<Point>men;
vector<Point>home;
int main() {
while(~sff(n, m), n + m) {
F.init();
men.clear();
home.clear();
for (int i = ; i < n ; i++) {
scanf("%s", tu[i]);
for (int j = ; j < m ; j++) {
if (tu[i][j] == 'm') men.push_back(Point(i, j));
if (tu[i][j] == 'H') home.push_back(Point(i, j));
}
}
int s=,len1=men.size(),len2=home.size(),t;
t=len1+len2+;
for (int i= ;i<len1 ;i++)
for (int j= ;j<len2 ;j++)
F.add(i+,j++len1,,cal(men[i],home[j]));
for (int i= ;i<=len1 ;i++) F.add(,i,,);
for (int i= ;i<=len2 ;i++) F.add(i+len1,t,,);
int cost = ;
F.solve(s, t, cost);
printf("%d\n", cost);
}
return ;
}

Going Home POJ - 2195 费用流板子题的更多相关文章

  1. Going Home POJ - 2195(费用流)

    就是一个简单题 四个月前a的一道题,今天又看到了,再a一遍吧. 好吧 我想多了 用了bfs求最短路  其实不用的 因为没有障碍物 #include <iostream> #include ...

  2. poj 2516 (费用流)

    题意:有N个供应商,M个店主,K种物品.每个供应商对每种物品的的供应量已知,每个店主对每种物品的需求量的已知,从不同的供应商运送不同的货物到不同的店主手上需要不同的花费,又已知从供应商m送第k种货物的 ...

  3. poj 2175 费用流消圈

    题意抽象出来就是给了一个费用流的残存网络,判断该方案是不是最优方案,如果不是,还要求给出一个更优方案. 在给定残存网络上检查是否存在负环即可判断是否最优. 沿负环增广一轮即可得到更优方案. 考虑到制作 ...

  4. HDU 3376 &amp;&amp; 2686 方格取数 最大和 费用流裸题

    题意: 1.一个人从[1,1] ->[n,n] ->[1,1] 2.仅仅能走最短路 3.走过的点不能再走 问最大和. 对每一个点拆点限流为1就可以满足3. 费用流流量为2满足1 最大费用流 ...

  5. Lunch Time(费用流变型题,以时间为费用)

    Lunch Time http://acm.hdu.edu.cn/showproblem.php?pid=4807 Time Limit: 4000/2000 MS (Java/Others)     ...

  6. Coding Contest(费用流变形题,double)

    Coding Contest http://acm.hdu.edu.cn/showproblem.php?pid=5988 Time Limit: 2000/1000 MS (Java/Others) ...

  7. POJ 1087 最大流裸题 + map

    A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15597   Accepted: 5308 ...

  8. POJ 3686 The Windy's(思维+费用流好题)

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

  9. 网络流板子/费用流板子 2018南京I题+2016青岛G题

    2018南京I题: dinic,链式前向星,数组队列,当前弧优化,不memset全部数组,抛弃满流点,bfs只找一条增广路,每次多路增广 #include <bits/stdc++.h> ...

随机推荐

  1. 关于java中“使用了未经检查或不安全的操作、有关详细信息,请使用 ——Xlint:unchecked重新编译”

    今天看<算法 第4版>排序章节时,发现了一个了一个小问题.先贴一下代码: public class Selection{ public static void main(String[]a ...

  2. 孤荷凌寒自学python第八十一天学习爬取图片1

    孤荷凌寒自学python第八十一天学习爬取图片1 (完整学习过程屏幕记录视频地址在文末) 通过前面十天的学习,我已经基本了解了通过requests模块来与网站服务器进行交互的方法,也知道了Beauti ...

  3. Android开发-API指南-<permission-tree>

    <permission-tree> 英文原文:http://developer.android.com/guide/topics/manifest/permission-tree-elem ...

  4. node.js应用--转载

    最近,在向大学生们介绍 HTML5 的时候,我想要对他们进行问卷调查,并向他们显示实时更新的投票结果.鉴于此目的,我决定快速构建一个用于此目的的问卷调查应用程序.我想要一个简单的架构,不需要太多不同的 ...

  5. Android - 时间 日期相关组件

    源码下载地址 : -- CSDN :  http://download.csdn.net/detail/han1202012/6856737 -- GitHub : https://github.co ...

  6. Coursera:Internet History ,Techornology and Security

    WEEK1 War Time Computing and Communication Bletchley Park 布莱彻利庄园:a top-secret code breaking effort b ...

  7. Beta完结--感想及吐槽

    Beta冲刺结束啦!!! Beta冲刺结束啦!!! Beta冲刺结束啦!!! 这时候每个人的心情肯定都是非常激动的.随着Beta冲刺的结束,折磨了我们一整个学期的软工实践也差不多结束了.(实在是太不容 ...

  8. android 出现Make sure the Cursor is initialized correctly before accessing data from it

    Make sure the Cursor is initialized correctly before accessing data from it 详细错误是:java.lang.IllegalS ...

  9. Ubuntu下FileZilla的安装

    FileZilla是一个免费而且开源的FTP客户端软件,共有两种版本:客户端版本.服务器版本.FileZilla有条理的界面和管理多站点的简化方式使得FileZilla Client成为一个方便高效的 ...

  10. 自定义类属性设置及setter、getter方法的内部实现

    属性是可以说是面向对象语言中封装的一个体现,在自定义类中设置属性就相当于定义了一个私有变量.设置器(setter方法)以及访问器(getter方法),其中无论是变量的定义,方法的声明和实现都是系统自动 ...