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 思路
应该算是这个算法的板子题了,感觉还是只有看自己的代码才是最容易懂的。
cap表示边的容量,w表示费用。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1024;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);
int n,m;
char mp[108][108];
struct node
{
int x,y;
}p1[maxn],p2[maxn];
int Head[maxn],Next[maxn*maxn],v[maxn*maxn],w[maxn*maxn],cap[maxn*maxn],cnt;
int t1,t2;int ans;
void init()
{
t1=1;cnt=t2=ans=0;
memset(Head,-1,sizeof(Head));
} void add(int x,int y,int z,int f){
// cout<<x<<" "<<y<<" "<<z<<endl;
v[cnt]=y;
w[cnt]=z;
cap[cnt]=f;
Next[cnt]=Head[x];
Head[x]=cnt++; v[cnt]=x;
w[cnt]=-z;
cap[cnt]=0;
Next[cnt]=Head[y];
Head[y]=cnt++;
}
bool vis[maxn];
int dis[maxn];
int prevv[maxn],preve[maxn];
int s,t;
bool spfa()
{
queue<int>q;
memset(vis,0,sizeof(vis));
for(int i=1;i<=t;i++){
dis[i]=inf;
} dis[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int k=Head[u];k!=-1;k=Next[k]){
if(cap[k]&&dis[v[k]]>dis[u]+w[k]){
dis[v[k]]=dis[u]+w[k];
prevv[v[k]]=u;
preve[v[k]]=k; if(!vis[v[k]]){
vis[v[k]]=true;
q.push(v[k]);
}
}
}
}
// for(int i=1;i<=t;i++){
// cout<<dis[i]<<" ";
// }
// cout<<endl;
// getchar();getchar();
if(dis[t]==inf){return false;}
else return true;
}
int min_cost_flow()
{
// fuck("???")
while(spfa()){
// cout<<"____"<<endl;
for(int i=t;i!=s;i=prevv[i]){
int k=preve[i];
cap[k]-=1;
cap[k^1]+=1;
}
// cout<<endl;
ans+=dis[t];
} } int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
init();
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++){
if(mp[i][j]=='m'){p1[++t1]=node{i,j};}
else if(mp[i][j]=='H'){p2[++t2]=node{i,j};}
}
}
s=1;t=t1+t2+1;
for(int i=2;i<=t1;i++){
add(s,i,0,1);
for(int j=1;j<=t2;j++){
add(i,j+t1,abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y),inf);
}
}
for(int i=1;i<=t2;i++){
add(i+t1,t,0,1);
} min_cost_flow();
printf("%d\n",ans);
} return 0;
}

  

 

Going Home POJ - 2195 (最小费用最大流)的更多相关文章

  1. poj 2195 最小费用最大流模板

    /*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...

  2. POJ - 2195 最小费用最大流

    题意:每个人到每个房子一一对应,费用为曼哈顿距离,求最小的费用 题解:单源点汇点最小费用最大流,每个人和房子对于建边 #include<map> #include<set> # ...

  3. poj 3422(最小费用最大流)

    题目链接:http://poj.org/problem?id=3422 思路:求从起点到终点走k次获得的最大值,最小费用最大流的应用:将点权转化为边权,需要拆点,边容量为1,费用为该点的点权,表示该点 ...

  4. POJ 2516 最小费用最大流

    每一种货物都是独立的,分成k次最小费用最大流即可! 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E[pe[v]^ ...

  5. POJ 2135 最小费用最大流 入门题

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19207   Accepted: 7441 Descri ...

  6. poj 2135最小费用最大流

    最小费用最大流问题是经济学和管理学中的一类典型问题.在一个网络中每段路径都有"容量"和"费用"两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择 ...

  7. poj 3680(最小费用最大流)

    题目链接:http://poj.org/problem?id=3680 思路:因为N<=200,而区间范围为[1,100000],因此需要离散化,去重,然后就是建图了相连两点连边,容量为k,费用 ...

  8. POJ 2315 最小费用最大流

    从1走到N然后从N走回来的最短路程是多少? 转换为费用流来建模. 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E ...

  9. POJ 2135 最小费用最大流

    题目链接 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18961   Accepted: 7326 D ...

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

    http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...

随机推荐

  1. qtp自动化测试-条件语句 if select case

    1 if 语句 if  condition  then end if If condition Then   [statements] [ElseIf condition-n Then   [else ...

  2. vue事件綁定

    事件綁定可以是一個句子,一個函數名稱,也可以是一個函數. 事件修飾符,按鍵修飾符.

  3. 另一个ado工具类

    using System;using System.Collections.Generic;using System.Text;using System.Data.SqlClient;using Sy ...

  4. 1.docker 数据卷的备份和恢复(非大数据量)

    在生产环境中使用 Docker,很多时候需要对数据进行持久化,或者进行容器间的数据共享. 容器中的管理数据主要有两种方式: 数据卷 (Data Volumes): 容器内数据直接映射到本地主机环境: ...

  5. 【python练习题】程序2

    2.题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40 ...

  6. React 学习(三) ---- state 和 事件处理函数

    在上两节中,我们讲述了props, 组件使用props进行渲染,但是这是一次性的, props渲染完成之后就不做任何事情了,但是现实中却不是这样的,当我们点击购物车上的加减按钮时,数量会自动加1或减1 ...

  7. JarvisOJ Basic easyRSA

    还记得veryeasy RSA吗?是不是不难?那继续来看看这题吧,这题也不难. 已知一段RSA加密的信息为:0xdc2eeeb2782c且已知加密所用的公钥: (N=322831561921859 e ...

  8. 基于docker部署使用ELK+FileBeat日志管理平台

    Docker从狭义上来讲就是一个进程,从广义上来讲是一个虚拟容器,专业叫法为 Application Container(应用容器).Docker进程和普通的进程没有任何区别,它就是一个普通的应用进程 ...

  9. MySql获取树型结构的所有子节点

    stackoverflow的解决方案,亲测有效: SELECT * FROM person WHERE department IN (SELECT department_id FROM departm ...

  10. 基准对象object中的基础类型----元组 (五)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...