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. TW实习日记:第18天

    今天的bug没有那么多了,都是些小bug,一下就改好了.或者是接口那边数据返回的有问题,通知一下同事就ok了.主要今天是在赶功能进度,然而有一个功能模块需求里并没有写,实在是不知道要做成什么样子,真的 ...

  2. MySQL三方面优化

    第一方面:30种mysql优化sql语句查询的方法1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用 ...

  3. 《Effective C++》读书笔记 条款03 尽可能使用const 使代码更加健壮

    如果你对const足够了解,只需记住以下结论即可: 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用于内的对象.函数参数.函数返回类型.成员函数本体. 编译器强制实施 ...

  4. 校招小白机考入坑之从键盘输入java的各种数据类型

    //1.从键盘输入一个整型(其他基本类型类似) Scanner sc =new Scanner(System.in); sc.hasNextInt(); int str1 = sc.nextInt() ...

  5. 【第四章】Shell 条件测试表达式

    shell中条件测试的三种格式: 格式1: test 条件表达式格式2: [ 条件表达式 ]格式3: [[ 条件表达式 ]] 使用test: [root@host- ~]# test -f file ...

  6. Office 365 E3功能

    本文简要总结了Office 365E3的功能

  7. ubuntu 18.04 LTS server系统安装失败问题解决

    准备自己搭一个服务器,USB引导盘的方式安装ubutun系统. 中途遇到两个问题,导致耗时比较久,记录如下. 问题一: installing system阶段卡主 具体描述: 配置镜像源地址以后,进入 ...

  8. 由一个hash字符串生成多个子hash字符串

    通过存储一个head hash,然后把子hash放到网络中 当然,也可以像默克尔树那样的,生成多级的子hash ,可以通过规则配置不同的hash 生成方式.倒置的默克尔树 我有一个文件,然后我把她分隔 ...

  9. Alpha发布——Thunder团队

    视频展示 视频链接: 爱奇艺: http://www.iqiyi.com/w_19ruzwru25.html      (画质清晰,但可能需多次刷新或重新打开页面,此问题因电脑型号和网络而异) 优酷: ...

  10. spring框架(2)— 面相切面编程AOP

    spring框架(2)— 面相切面编程AOP AOP(Aspect Oriented Programming),即面向切面编程. 可以说是OOP(Object Oriented Programming ...