HD 1533 Going Home(最小费用最大流模板)
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3666 Accepted Submission(s):
1884
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.
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.
integer, which is the minimum amount, in dollars, you need to pay.
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
10
28
...H....
...H....
...H....
mmmHmmmm
以所有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(最小费用最大流模板)的更多相关文章
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- 图论算法-最小费用最大流模板【EK;Dinic】
图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...
- HDU3376 最小费用最大流 模板2
Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)To ...
- 洛谷P3381 最小费用最大流模板
https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...
- 最大流 && 最小费用最大流模板
模板从 这里 搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) ; const int INF = 0x3f3f3f3f; struct Edge { int from ...
- 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 ...
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- hdu 1533 Going Home 最小费用最大流 入门题
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- luogu 3376 最小费用最大流 模板
类似EK算法,只是将bfs改成spfa,求最小花费. 为什么可以呢,加入1-3-7是一条路,求出一个流量为40,那么40*f[1]+40*f[2]+40*f[3],f[1]是第一条路的单位费用,f[2 ...
- POJ2135 最小费用最大流模板题
练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...
随机推荐
- 基于 URL 的权限控制
先不用框架,自己实现一下 数据库 /* SQLyog v10.2 MySQL - 5.1.72-community : Database - shiro *********************** ...
- 千份位Javascript Thousand Separator / string format
function Separator(str){ return str.split(/(\d+)(\d{3})(\d{3})(\d{3})(\d{3})/).join(',').replace(/^, ...
- Log4Net写入到数据库配置过程中的一些小问题备忘
问题1: 在公司进行log4net写入服务器配置的时候,一切正常,但是在家里的机器上,就频繁出现这个问题: SQL Server 2008 报错:已成功与服务器建立连接,但是在登录前的握手期间发生错误 ...
- Android开发探秘之一:创建可以点击的Button
感觉到自己有必要学习下手机开发方面的知识,不论是为了以后的工作需求还是目前的公司项目. 当然,任何新东西的开始,必然伴随着第一个HelloWorld,Android学习也不例外.既然才开始,我就不做过 ...
- JS案例之5——移动端触屏滑动
移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件 ...
- 中科院Oracle 10G 数据库系统培训视频教程(828MB )
中科院Oracle 10G 数据库系统培训视频教程(828MB )第一章.安装及体系结构概述 Oracle数据库基础知识第二章.SQL*PLUS 基础.实例的创建启动与关闭第三章.SQL语言基础第四 ...
- Android使用service后台更新计划任务
Service是Android的四大组件之一,这里就不再过多的去描述,下面主要实现启动应用时候利用service后台执行计划任务,退出应用后,关闭service,只存在整个应用的周期中. 首先使用se ...
- UltraEdit编辑器使用心得之正则表达式篇
ultraEdit 中通过Ctrl+R 可以快速进行文本替换等处理操作,如果在这中间用一些正则表达式那将帮助NI更高效的进行文字处理操作,相关正则表达式列述如下: % 匹配行首 - 表示搜索字符串必须 ...
- struts2+Hibernate实现用户登陆功能
实现的功能,在登陆页面输入Username和PassWord后,将username和password通过Hibernate匹对数据库是否含有一样的username和password,若有则登陆进去,若 ...
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...