/*Source Code
Problem: 2195 User: HEU_daoguang
Memory: 1172K Time: 94MS
Language: G++ Result: Accepted
Source Code
*/
#include <iostream>
#include <stdio.h>
#include <queue>
#include <math.h>
#include <string.h>
using namespace std;
#define V 6005
#define E 10010000
#define inf 999999999
int n,m;
char map[][];
int hp[V][],mp[V][]; int vis[V];
int dist[V];
int pre[V]; struct Edge{
int u,v,c,cost,next;
}edge[E];
int head[V],cnt;
void init(){
cnt=;
memset(head,-,sizeof(head));
} void addedge(int u,int v,int c,int cost){
edge[cnt].u=u;edge[cnt].v=v;edge[cnt].cost=cost;
edge[cnt].c=c;edge[cnt].next=head[u];head[u]=cnt++; edge[cnt].u=v;edge[cnt].v=u;edge[cnt].cost=-cost;
edge[cnt].c=;edge[cnt].next=head[v];head[v]=cnt++;
} bool spfa(int begin,int end){
int u,v;
queue<int> q; for(int i=;i<=end+;i++){
pre[i]=-;
vis[i]=;
dist[i]=inf;
}
vis[begin]=;
dist[begin]=;
q.push(begin); while(!q.empty()){ u=q.front();
q.pop();
vis[u]=; for(int i=head[u];i!=-;i=edge[i].next){
if(edge[i].c>){
v=edge[i].v;
if(dist[v]>dist[u]+edge[i].cost){
dist[v]=dist[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
} } return dist[end]!=inf;
} int MCMF(int begin,int end){
int ans=,flow;
int flow_sum=; while(spfa(begin,end)){ flow=inf;
for(int i=pre[end];i!=-;i=pre[edge[i].u])
if(edge[i].c<flow)
flow=edge[i].c;
for(int i=pre[end];i!=-;i=pre[edge[i].u]){
edge[i].c-=flow;
edge[i^].c+=flow;
}
ans+=dist[end]*flow;
flow_sum+=flow; }
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF){
if(n== && m==) break;
for(int i=;i<n;i++){
scanf("%s",map[i]);
}
int hcnt=,mcnt=;
for(int i=;i<n;i++)
for(int j=;j<m;j++){
if(map[i][j]=='H'){
hp[hcnt][]=i;
hp[hcnt][]=j;
hcnt++;
}
if(map[i][j]=='m'){
mp[mcnt][]=i;
mp[mcnt][]=j;
mcnt++;
}
}
hcnt--;
mcnt--;
init();
for(int i=;i<=hcnt;i++){
addedge(,i,,);
//addedge(i,0,1,0);
}
for(int j=;j<=mcnt;j++){
addedge(hcnt+j,hcnt+mcnt+,,);
//addedge(hcnt+mcnt+1,hcnt+j,1,0);
}
for(int i=;i<=hcnt;i++)
for(int j=;j<=mcnt;j++){
addedge(i,hcnt+j,,fabs(hp[i][]-mp[j][])+fabs(hp[i][]-mp[j][]));
//addedge(hcnt+j,i,1,fabs(hp[i][0]-mp[j][0])+fabs(hp[i][1]-mp[j][1]));
}
int res=MCMF(,hcnt+mcnt+);
printf("%d\n",res);
}
return ;
}
/*
2
.m
H.
5
HH..m
.....
.....
.....
mm..H
8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
20
..mm..H..H.H...HHH.m
m.H...H.....H......m
..H...mm.........m..
Hm.m..H.H...H..m....
mH.Hm....mH........H
m............m......
.m..H...........H..m
H.m.H.....H.......m.
...m..Hm.....m.H...H
..H...H....H......mH
..m.m.....m....mm...
..........H.......H.
...mm......m...H....
.....m..H.H......m.m
.H......mm.H.m.m.m.m
HH..........HH..HH..
...m..H........Hm...
....H.....H...mHm...
H...........m......m
....m...H.m.....m...
20
...Hm.m.HHH...Hmm...
.H........m.......H.
.......H...H.H......
....HmH.m....Hm..m..
....m..m............
H..H.........m....H.
.m.H...m...mH.m..H..
.mH..H.H......m...m.
...mH...H.......m...
..Hm..H..H......m.m.
..mH...H.m..m.H..HH.
m.m......m........m.
...mH..m.....mH.....
....m.H.H..........H
....H.......H....m.H
H.mH.......m.......H
..............m.HH.H
..H.........m.m.m...
.........mH.....mmm.
...mH.m.m.....H..m..
20
H.H.......H....m....
.....m..H......H..H.
...H..............m.
mH..mm..m...H.......
......H....mm.H.....
.mH..mm.....mH.H...H
.........HHH........
......H.H...mm......
.m..m.H...mHmm...HH.
mm..Hmm.H..m...m.H.m
H.Hm.m.m.....m......
...........m.......H
......m......H...m..
....H..........Hm...
.H..H.m....m........
...H....Hm..........
m.H.mHm.m.m...H...H.
.m..........m.......
H......H...HmHHm..H.
..H..m.m...m.H..H...
20
.m..m..Hm...........
.m..H.H...m.m.m...H.
........m..mH....H..
..H...........Hm.H.m
H..H.m........mm..m.
H.......m...........
..m..Hmmmm...m..mH..
..H.Hm...H..........
H....m.......mm.....
....m..m.....m.....m
.H.m.H...H.....H....
.m........mm..H...H.
..m.......H.mH..mm.H
.......Hm...HH....H.
...mm....HHH........
..H.m..H........m...
H.........H.........
HH.H.....m.H..Hm....
...H.m...H.Hm.....m.
.H..mH..H..H........
20
m.........m.......m.
..m.H....m....m...m.
m...H.m.....H.H.....
.....H.Hm.m...m.....
..mH...H.H.m.H...H..
H....H......m.....m.
..................H.
.m..m.Hm......m..H..
....H..H.m.....H...H
....m.H......m.H...m
....HH...H...H......
..H.....m......H.H..
mmH...mmm.....m.....
..m.......m...mmH...
......H.H..m...Hm..H
HHHm.H.m........H...
...mHm.......m....m.
.....mmH.H..H.....m.
......m..H.....m...H
..HH..m...mH......H.
20
m.HHm..HH..m.mHm....
mm..H...............
m...HH.......m.H....
..mH.m.m.......mmH..
H.m........m.......H
m.H....m....m..m...H
....m......mm.......
.m.H....m..H..m..H..
H....m......H.......
...H...........m.m.H
......H...m...H..m..
.mH..H.H.....m......
...m.....m.H...HmH.H
m.......H..H.H..mm.H
...H.........Hm.HH..
.m....H.....m.HHm...
...HHH...........m..
m............H......
.....m..mm.....m....
.....m..H..H..H....H
20
....H.............m.
.....HH..mH..Hm..H..
m...........mH....mm
..m..m.H......m....m
.H..........mHH....m
...........m..H.m...
..H...H.........mHm.
......H...........H.
H.....H.....H..m....
H.H..H..m...m..mH.m.
....H...m.H.mHmm.mHm
..mmm...H....m....H.
.........m..m.......
.m.H....Hm....m.....
.....H.......HH...mH
..H..H....m.m.....HH
.Hm.............H...
H...Hm.......H.m.m..
.....m..HH...H.....m
........mHmmH..m....
20
.....H.......H...m.m
.m..H.m.m....m......
m.H.HHH..mm.........
H...mH.mH...........
..mHm..m.m......m..m
H.HH.....m...m......
H.mH....H......H....
...mH.m.mHmH...H....
........H.....m.....
..H.......HmH...H...
......m...HH.m......
.H..m.H...H.........
...H...m..m..m...m..
.mH..HH......m...H.. ...m....H.H.H.m.....
.........H.m........
..m..H...H......H...
mmH..mH.....m.H..H..
H....mm...H.m...m.mm
......m.............
20
....mH..m...m.....m.
..m......mHm...H....
.H.....mHm....H..H..
...HH..........m.m..
..m..mm........m....
...m.....H..........
..mH..H...m.........
...H.H.....m..mH..m.
..H.........Hm.Hm..H
...........H......m.
.............H...mm.
H.m.....Hm.H.m......
....Hm..m..mm.H...m.
...H.H.H......H.Hm..
H.m............m....
..mH.m.m...m..H.m..H
HH.H....m.H..H...m..
.....H.....H...H...H
........mH.HHm.....m
.H.H.....mmH......m.
20
.mH........m.mmH..H.
m....H........H..H..
.........Hm.m.m.....
....H.H...m.........
.H....m.............
HH.....H.....H.HH...
mmmmmm.H..m..m......
.Hm.H...H.H..m.H....
.........m..m.mHmHH.
...m.m....m..H.Hm..H
...Hm....H..m....m..
...mH.....m.......m.
.H...HmmH..H.....H..
m.H...m.....mmH....H
.m.H......m...H.....
H........m..Hm......
.......m...........m
...m........m...H...
.........m...H......
HH..H..m...H......H.
*/

上面的网上大牛的代码,我看的好像和我的模板差不多,还有测试样例,我就复了一下,下面的是我的代码

Going Home
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 19827   Accepted: 10080

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

 
求得就是每个人需要到每个房子里,一个房子只能装下一个人,问最少的开销,没走一个单元格的花费就以一元
可以直接建图,建出每个人到各个房子的距离,连成一条边,流量cap为1,花费cost为dis,即为横坐标的绝对值差加上纵坐标的绝对值差;
之后建立一个超级原点和一个超级会点,让超级原点连到每一个人,cap为1,cost为0,同理让每一个房子链接到超级汇点,cap为1,cost为0
之后跑框斌的最小费用最大流算法模板就可以过了,还要注意个问题就是总的点数为cnth+cntm+2
还有一个需要注意的地方是本题的范围是100*100;
所以点和边的数值尽量开的大一些
下面贴上代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;
//最小费用最大流,求最大费用只需要取相反数,结果取相反数即可。
//点的总数为 N,点的编号 0~N-1
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow,cost;
} edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1
void init()
{
tol = ;
memset(head,-,sizeof (head));
}
void addedge (int u,int v,int cap,int cost){
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = ;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = ;
edge[tol].cost = -cost;
edge[tol].flow = ;
edge[tol].next = head[v];
head[v] = tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i = ; i < N; i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -; i = edge[i]. next)
{
int v = edge[i]. to;
if(edge[i].cap > edge[i].flow &&
dis[v] > dis[u] + edge[i]. cost )
{
dis[v] = dis[u] + edge[i]. cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -)return false;
else return true;
}
//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s,int t,int &cost)
{
int flow = ;
cost = ;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t]; i != -; i = pre[edge[i^].to])
{
if(Min > edge[i].cap - edge[i]. flow)
Min = edge[i].cap - edge[i].flow;
}
for(int i = pre[t]; i != -; i = pre[edge[i^].to])
{
edge[i].flow += Min;
edge[i^].flow -= Min;
cost += edge[i]. cost * Min;
}
flow += Min;
}
return flow;
}
char map[];
struct node1{
int x, y;
}hh[];
struct node2{
int x,y;
}mm[];
int main(){
int n,m,sta;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==&&m==)
break;
memset(hh,,sizeof(hh));
memset(mm,,sizeof(mm));
memset(map,,sizeof(map));
memset(pre,,sizeof(pre));
memset(dis,,sizeof(dis));
memset(vis,false,sizeof(vis));
memset(edge,,sizeof(edge));
memset(hh,,sizeof(hh));
memset(mm,,sizeof(mm));
init();
int u,v,w;
int cnth=,cntm=;
for(int i=;i<n;i++){
scanf("%s",map);
for(int j=;j<m;j++){
if(map[j]=='H'){
hh[++cnth].x=i;
hh[cnth].y=j;
}
if(map[j]=='m'){
mm[++cntm].x=i;
mm[cntm].y=j;
}
}
}
N=cntm+cnth+;
for(int i=;i<=cntm;i++){
for(int j=;j<=cnth;j++){
addedge(i,j+cntm,,abs(mm[i].x-hh[j].x)+abs(mm[i].y-hh[j].y));
addedge(j+cntm,i,,abs(mm[i].x-hh[j].x)+abs(mm[i].y-hh[j].y));
}
}
int ans1=;
for(int i=;i<=cntm;i++){
addedge(,i,,);
}
for(int j=cntm+;j<=cnth+cntm;j++){
addedge(j,cnth+cntm+,,);
} int temp=minCostMaxflow(,cnth+cntm+,ans1);
printf("%d\n",ans1); }
}

最新文章

  1. jQuery源码分析系列(37) : Ajax 总结
  2. LogStash配置、使用(三)
  3. JQuery实现仿sina新浪微博新鲜事滚动
  4. iOS开发之身份证号码校验
  5. . ToString(),Convert.ToString(),(string),as比较:
  6. Sqrt(x)
  7. Delphi遍历文件夹
  8. 数往知来 ASP.NET 表单的提交_url传值_重定向 &lt;十八&gt;
  9. STL学习二:Vector容器
  10. jQuery对象和DOM对象原来不一样啊
  11. New ipad安装Perl支持安装nikto
  12. Java解惑七:很多其它类之谜
  13. jquery 弹出登陆框,简单易懂!修改密码效果代码
  14. deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II 听课笔记
  15. Linux下C语言生成可执行文件的过程
  16. Bomb HDU - 5934 (Tarjan)
  17. BSOJ 2423 -- 【PA2014】Final Zarowki
  18. 算法 数组中出现次数最多的数字 MD
  19. 关于chrome的开发调试方式
  20. [翻译] GMCPagingScrollView

热门文章

  1. 洛谷 P2014 选课
  2. [uestc oj]H - 邱老师选妹子
  3. uva806 Spatial Structures 空间结构 (黑白图像的四分树表示)
  4. 剑指offer38 数字在排序数组中出现的次数
  5. iOS快速开发框架--Bee Framework
  6. c#自定义类型之间的转换(强制类型转换)
  7. RSA与AES实现数据加密传输
  8. paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之全0/1/z/x的SV写法
  9. 将php数组转js数组,js如何接收PHP数组,json的用法
  10. Python头脑风暴3