/*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); }
}

poj 2195 最小费用最大流模板的更多相关文章

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

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

  2. 图论算法-最小费用最大流模板【EK;Dinic】

    图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...

  3. HDU3376 最小费用最大流 模板2

    Matrix Again Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)To ...

  4. 洛谷P3381 最小费用最大流模板

    https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...

  5. 最大流 && 最小费用最大流模板

    模板从  这里   搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) ; const int INF = 0x3f3f3f3f; struct Edge { int from ...

  6. POJ 2135 Farm Tour (最小费用最大流模板)

    题目大意: 给你一个n个农场,有m条道路,起点是1号农场,终点是n号农场,现在要求从1走到n,再从n走到1,要求不走重复路径,求最短路径长度. 算法讨论: 最小费用最大流.我们可以这样建模:既然要求不 ...

  7. 最小费用最大流模板(POJ 2135-Farm Tour)

    最近正好需要用到最小费用最大流,所以网上就找了这方面的代码,动手写了写,先在博客里存一下~ 代码的题目是POJ2135-Farm Tour 需要了解算法思想的,可以参考下面一篇文章,个人觉得有最大流基 ...

  8. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的 ...

  9. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

随机推荐

  1. Python + selenium之unitest(1)

    单元测试负责对最小的软件设计单元(模块)进行验证,它使用软件设计文档中对模块的描述作为指南,对重要的程序进行测试以发现模块中的错误. 下面演示不用测试框架的单元测试: # 计算器类 class Cou ...

  2. POJ 3260 The Fewest Coins 最少硬币个数(完全背包+多重背包,混合型)

    题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬 ...

  3. POJ Dollar Dayz 美元假日(完全背包,常规+大数)

    题意:给出整数n和k,n代表拥有的钱数量,k代表有k种工具,其价钱分别为1~k.求n元能有多少种购买的方案. 思路:k最大有100,数量过大,要用大数.其他的基本和完全背包一样. #include & ...

  4. 51nod 1631 小鲨鱼在51nod小学

    基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务.   ...

  5. 如何在程序中加入Growl通知

    Growl for Windows – Mac 样式的信息提示工具.目前已经支持的软件包括:Outlook,Visual Studio 等以及一个利用命令行从本地或者远程发送消息过来的工具 .Grow ...

  6. java基础—配置环境变量

    前言 学习java的第一步就要搭建java的学习环境,首先是要安装JDK,JDK安装好之后,还需要在电脑上配置"JAVA_HOME”."path”."classpath& ...

  7. python-IE浏览器调用

    IE浏览器驱动添加 selenium官网有提供下载http://code.google.com/p/selenium/downloads/list 这里我用的是IEDriverServer_Win32 ...

  8. 01_7_Struts_用Action的属性接收参数

    01_7_Struts_用Action的属性接收参数 1. 配置struts.xml文件 <package name="user" namespace="/user ...

  9. pandas实践——美国人口分析

    1.导入文件,并查看数据样本 abbr = pd.read_csv("./state-abbrevs.csv")areas =pd.read_csv("./state-a ...

  10. C语言中的32个关键字

    C语言中的32个关键字 数据类型关键字(12个) (1)     char:声明字符型变量或函数 (2)     double:声明双精度变量或函数 (3)     enum:声明美剧类型 (4)   ...