Going Home

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3666    Accepted Submission(s):
1884

Problem 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
题意:

...H....

...H....

...H....

mmmHmmmm

...H....
...H....
...H....
问所有H移动到所有m上花费最少的步数

以所有H 到 所有m 连一条边,边的权重为两者者距离,然后加一个超级源点和汇点,与原点的流量为1,费用为0,汇点也是一样。

转换成了求嘴小费用最大流问题;

//刘汝佳模板
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN = 400;
const int MAXM = 200000;
const int INF = 0x3f3f3f3f;
struct Edge
{
int from,to,cap,cost,flow;
Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),cost(f),flow(w){}
};
vector<Edge> edge;
vector<int> g[MAXN];
int inq[MAXN],d[MAXN],p[MAXN],a[MAXN];
int NN,MM;
int topH,topP;
struct point
{
int x,y;
}H[MAXN],P[MAXN]; void input()
{
char ch;
topH = topP = 0;
for(int i = 1; i <= NN; i++)
{
for(int j = 1; j <= MM; j++)
{
scanf("%c",&ch);
if(ch == 'H')
{
topH++;
H[topH].x = i;
H[topH].y = j;
}
else if(ch == 'm')
{
topP++;
P[topP].x = i;
P[topP].y = j;
}
}
getchar();
}
}
void AddEdge(int from, int to, int cap, int cost)
{
edge.push_back(Edge(from,to,cap,cost,0));
edge.push_back(Edge(to,from,0,-cost,0));
int m = edge.size();
g[from].push_back(m - 2);
g[to].push_back(m - 1);
}
int MCMF(int s,int t,int& flow, int& cost)
{ for(int i = 0; i < MAXN; i++)
d[i] = INF;
memset(inq, 0, sizeof(inq));
d[s] = 0;
inq[s] = 1;
p[s] = 0;
a[s] = INF; queue<int> myque;
myque.push(s);
while(myque.empty() == 0)
{
int u = myque.front();
myque.pop();
inq[u] = 0;
for(int i = 0; i < (int)g[u].size(); i++)
{
Edge e = edge[ g[u][i] ];
if(e.cap > e.flow && d[e.to] > d[u] + e.cost)
{
d[e.to] = d[u] + e.cost;
p[e.to] = g[u][i];
a[e.to] = min(a[u], e.cap - e.flow);
if(inq[e.to] == 0)
{
myque.push(e.to);
inq[e.to] = 1;
}
}
}
}
if(d[t] == INF)
return false;
flow += a[t];
cost += d[t] * a[t]; for(int u = t; u != s; u = edge[ p[u] ].from)
{
edge[ p[u] ].flow += a[t];
edge[ p[u] ^ 1].flow -= a[t];
}
return true; }
int creatGraph()
{
int ans = 0,flow = 0;
int MN = topH + topP;
for(int i = 1; i <= topP; i++)
{
for(int j = 1; j <= topH; j++)
{
int t = abs(H[i].x - P[j].x) + abs(H[i].y - P[j].y); //距离最为费用
AddEdge(i,topP + j, 1, t); // 边i到topP+j,把所有H.m点都排号序号
}
} for(int i = 1; i <= topP; i++)
AddEdge(MN + 1, i, 1, 0); //源点到M点
for(int i = topP + 1; i <= MN; i++)
AddEdge(i, MN + 2, 1,0); // H点到汇点
while(MCMF(MN + 1, MN + 2, flow, ans) );
return ans;
}
int main()
{
while(scanf("%d%d",&NN,&MM) != EOF)
{
if(NN == 0 && MM == 0)
break;
getchar();
for(int i = 1; i < MAXN; i++)
g[i].clear();
edge.clear();
input();
printf("%d\n",creatGraph());
}
return 0;
}

  

HD 1533 Going Home(最小费用最大流模板)的更多相关文章

  1. POJ 2195 & HDU 1533 Going Home(最小费用最大流)

    这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...

  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. hdu 1533 Going Home 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...

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

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

  8. hdu 1533 Going Home 最小费用最大流 入门题

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  9. luogu 3376 最小费用最大流 模板

    类似EK算法,只是将bfs改成spfa,求最小花费. 为什么可以呢,加入1-3-7是一条路,求出一个流量为40,那么40*f[1]+40*f[2]+40*f[3],f[1]是第一条路的单位费用,f[2 ...

  10. POJ2135 最小费用最大流模板题

    练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...

随机推荐

  1. Windows Phone 简介

    中文官网 https://dev.windowsphone.com/zh-cn Windows Phone SDK 7.1 http://www.microsoft.com/zh-cn/downloa ...

  2. IPAdr.exe破解[练手]

    [文章标题]: IPAdr.exe破解[软件名称]: IPAdr.exe[加壳方式]: 无[编写语言]: delphi[使用工具]: OD[作者声明]: 失误之处敬请诸位大侠赐教!---------- ...

  3. 可以这样去理解group by和聚合函数(转)

    http://www.cnblogs.com/wuguanglei/p/4229938.html 写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不 ...

  4. Google protocol buffer在windows下的编译

    在caffe框架中,使用的数据格式是google的 protocol buffer.对这个不了解,所以,想简单学习一下.简单来说,Protocol Buffer 是一种轻便高效的结构化数据存储格式,可 ...

  5. C++系列: 如何将十六机制的字符串转成整数

    bool convertHexStringToInt(char* pstrHex, unsigned long* pResult) { ) return false; else return true ...

  6. LeetCode 334 Increasing Triplet

    这个题是说看一个没有排序的数组里面有没有三个递增的子序列,也即: Return true if there exists i, j, k such that arr[i] < arr[j] &l ...

  7. jQuery上传插件Uploadify使用帮助

    Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.它的功能特色总结如下: 支持单文件或多文件上传,可控制并发上传的文件数 在服务器端支持各种语言与之配合使用,诸如PHP, ...

  8. 再次遇到\r\n转\r问题

    帮助小伙伴做jenkins的环境搭建.以为5分钟的事情,但是发现了一个诡异的问题.总是提示SVN的url不合法“URL '%s' is not properly URI-encoded”. 由于选择了 ...

  9. 简述WebService的使用(二)

    上集回顾 上一篇我简单的介绍了一下整个WebService建立和后端访问的过程,如果感兴趣可以看一看:简述WebService的使用(一) //如有不懂请留言,觉得有用请点赞 内容提要 这一篇主要介绍 ...

  10. Object C学习笔记24-关键字总结

    学习Object C也有段时间了,学习的过程中涉及到了很多Object C中的关键字,本文总结一下所涉及到的关键字以及基本语法. 1.  #import #import <> 从syste ...