hdu 1533 Going Home 最小费用最大流 (模板题)
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7405 Accepted Submission(s): 3907
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.
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.

#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
#define ll long long
#define mx 0x3f3f3f3f
using namespace std;
int cap[][],cost[][],flow[][];//cap是容量,cost是花费,flow是流量
int pre[],dis[],vis[],cnt[];//pre是记录增广路的前驱节点,dis[i]是记录源点到节点i的最小距离
//vis[i]标记点是否在队列中,cnt[i]记录点i进入队列的次数
char str[][];
struct node
{
int x;
int y;
}s[],e[]; int n,m;
int st,endd,nn,mm;//st是源点,endd是汇点
int mn_cost,mx_flow;
int spfa()
{
for(int i=;i<n;i++)
dis[i]=mx;
memset(vis,,sizeof(vis));
memset(cnt,,sizeof(cnt)); queue<int>p;
p.push(st);//st是起点
vis[st]=;
cnt[st]=;
dis[st]=;
while(!p.empty())
{
int now=p.front();
p.pop();
vis[now]=;
for(int i=;i<n;i++)
{
if(cap[now][i]>flow[now][i]&&dis[i]>dis[now]+cost[now][i])//这里将费用看成是长度,求源点到汇点的最小距离
{
dis[i]=dis[now]+cost[now][i];
pre[i]=now;
if(vis[i]==)
{
p.push(i);
vis[i]=;
cnt[i]++;
if(cnt[i]>n)
return ;
}
}
}
}
if(dis[endd]>=mx)
return ;
return ;
}
void bfs(int n)//顶点数
{
memset(flow,,sizeof(flow));
mx_flow=;
mn_cost=;
while(spfa())
{
int f=mx;
for(int i=endd;i!=st;i=pre[i])
f=min(f,cap[pre[i]][i]-flow[pre[i]][i]); for(int i=endd;i!=st;i=pre[i])//更新流量
{
flow[pre[i]][i]+=f;
flow[i][pre[i]]-=f;
}
mn_cost+=dis[endd]*f;
mx_flow+=f; }
}
int main()
{
while(~scanf("%d%d",&nn,&mm)&&nn&&mm)
{
//这道题需要自己将输入转化,建立一个有向图
int cnt1=,cnt2=;
for(int i=;i<nn;i++)
{
scanf("%s",str[i]);
for(int j=;j<mm;j++)
{
if(str[i][j]=='m')//起点
{
cnt1++;
s[cnt1].x=i;
s[cnt1].y=j;
}
if(str[i][j]=='H')//终点
{
cnt2++;
e[cnt2].x=i;
e[cnt2].y=j;
}
}
}
n=cnt1+cnt2+;//加上源点和汇点,共有n个点,[0,n-1]
st=;//源点
endd=cnt1+cnt2+;//汇点
memset(cap,,sizeof(cap));
memset(cost,,sizeof(cost));
for(int i=;i<=cnt1;i++)//初始化源点到任意起点的花费为0,容量为1;
{
cap[][i]=;
cost[][i]=;
cost[i][]=;
}
for(int i=;i<=cnt2;i++)//初始化汇点到所有终点的花费为0,容量为1;
{
cap[i+cnt1][endd]=;
cost[i+cnt1][endd]=;
cost[endd][i+cnt1]=;
}
for(int i=;i<=cnt1;i++)//初始化起点到终点的花费和容量
{
for(int j=;j<=cnt2;j++)
{
cap[i][cnt1+j]=;
cost[i][cnt1+j]=abs(s[i].x-e[j].x)+abs(s[i].y-e[j].y);
cost[cnt1+j][i]=-cost[i][cnt1+j];
}
}
bfs(n);
printf("%d\n",mn_cost);
}
return ;
}
hdu 1533 Going Home 最小费用最大流 (模板题)的更多相关文章
- hdu 1533 Going Home 最小费用最大流 入门题
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- 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 ...
- POJ2135 最小费用最大流模板题
练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...
- 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]
题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU3376 最小费用最大流 模板2
Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)To ...
- 图论算法-最小费用最大流模板【EK;Dinic】
图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...
随机推荐
- sparksql报错
执行时报错: org.apache.spark.sql.AnalysisException: Unable to generate an encoder for inner class `cn.itc ...
- nginx windows下重新加载配置
运行过程中,有个节点部分服务出现故障,像将其下线修复, 使用nginx -t; nginx -s reload 重新加载配置 得到错误"nginx: [error] OpenEvent(&q ...
- php cli 下 php.ini 配置
// 查看phpcli 模式下 扩展 php -m // 查看php cli 版本 php -v 查看命令行的ini路径,命令行下运行 php --ini Loaded Configuration F ...
- 五年C语言程序员,是深耕技术还是走管理?
从进入程序员行列开始(2013年6月),到现在为止(2019年2月),已经有五年半了. 一路波折,已经从无知菜鸟走到了意识觉醒的老鸟了. 薪资变化情况如下: 2013年:2000元/月 ( ...
- druid监控sql完整版
利用Druid实现应用和SQL监控 一.关于Druid Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. D ...
- MySQL之innodb和myisam的区别
innodb和myisam的区别: MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型, .frm文件存储表定义, 数据文件的扩展名为.MYD, 索引文件的扩展名是 ...
- 学习不一样的vue实战(2): 项目分析
学习不一样的vue实战(2): 项目分析 首先 首发博客: 我的博客 项目源码: 源码(喜欢请star) 项目预览: 预览 上一章: <学习不一样的vue(1)实战:环境搭建> 我的Q群: ...
- springmvc 请求出现400错误(当传入的参数类型是Date时加上下面代码试试)
@InitBinder protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) t ...
- ubunut18.04 下安装 gitlab ce版,使用清华源
gitlab官方的ubuntu安装说明 https://about.gitlab.com/install/#ubuntu 该安装说明介绍的是gitlab-ee版本 按照该说明也能安装gitlab-ce ...
- 手机号----IP api
/* *手机号码API */ $fPArr = iconv("gbk","utf-8",file_get_contents($fphone)); echo $f ...