hdu 1533 Going Home 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533
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.
题意描述:在n*m的矩阵格子里有x个人要走到x个房间里,每个房间里只能放一人,人在目前所在的格子处向上下左右相邻的格子走一步就花费1美元,问最后全部的人走到房间后最小的花费。
算法分析:这道题可以用KM算法或者最小费用最大流算法解之,这里讲解一下最小费用最大流的方法。
新增源点from和汇点to,from->人(w为1,cost为0)
房子->to(w为1,cost为0)
每个人->每间房(w为1,cost为最短路径的美元花费)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int maxn=+;
const int M = +; int n,m,from,to;
struct node
{
int v,flow,cost;
int next;
}edge[M*];
int head[maxn],edgenum;
int dis[maxn],pre[maxn],pid[maxn],vis[maxn]; void add(int u,int v,int flow,int cost)
{
edge[edgenum].v=v ;edge[edgenum].flow=flow ;
edge[edgenum].cost=cost ;edge[edgenum].next=head[u];
head[u]=edgenum++; edge[edgenum].v=u ;edge[edgenum].flow=;
edge[edgenum].cost=-cost ;edge[edgenum].next=head[v];
head[v]=edgenum++;
} int spfa()
{
for (int i= ;i<=to ;i++)
{
dis[i]=inf;
vis[i]=;
}
queue<int> Q;
Q.push(from);
dis[from]=;
vis[from]=;
while (!Q.empty())
{
int u=Q.front() ;Q.pop() ;
vis[u]=;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].v;
if (edge[i].flow> && dis[v]>dis[u]+edge[i].cost)
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=u;
pid[v]=i;
if (!vis[v])
{
vis[v]=;
Q.push(v);
}
}
}
}
return dis[to];
} int mincost()
{
int aug=,maxflow=;
int ans=,tmp=;
while ()
{
tmp=spfa();
if (tmp==inf) break;
aug=inf;
for (int i=to ;i!=from ;i=pre[i])
{
if (edge[pid[i] ].flow<aug)
aug=edge[pid[i] ].flow;
}
for (int i=to ;i!=from ;i=pre[i])
{
edge[pid[i] ].flow -= aug;
edge[pid[i]^ ].flow += aug;
}
maxflow += aug;
ans += tmp;
}
return ans;
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
if (!n && !m) break;
memset(head,-,sizeof(head));
edgenum=;
char str[][];
memset(str,,sizeof(str));
for (int i= ;i<=n ;i++)
{
scanf("%s",str[i]+);
}
from=n*m+;
to=from+;
int h[],c[],cnt=;
int h2[],c2[],cnt2=;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=m ;j++)
{
if (str[i][j]=='m')
{
add(from,(i-)*m+j,,);
h[cnt]=i ;c[cnt]=j ;cnt++ ;
}
else if (str[i][j]=='H')
{
add((i-)*m+j,to,,);
h2[cnt2]=i ;c2[cnt2]=j ;cnt2++ ;
}
}
}
for (int i= ;i<cnt ;i++)
{
for (int j= ;j<cnt2 ;j++)
add((h[i]-)*m+c[i],(h2[j]-)*m+c2[j],,abs(h[i]-h2[j])+abs(c[i]-c2[j]));
}
printf("%d\n",mincost());
}
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 最小费用最大流 (模板题)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU 5988.Coding Contest 最小费用最大流
Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 3667(拆边+最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU–5988-Coding Contest(最小费用最大流变形)
Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 1853 Cyclic Tour 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 There are N cities in our country, and M one-way ...
随机推荐
- Windows下安装redis,并与PHP使用
一.在windows下安装redis: redis的官方网站下载地址:http://redis.io/download 进入以上网址之后,请见以下的图片操作下载redis: 第一步: 第二步:在对应的 ...
- C# 标准查询表达式
一.标准查询运算符 1.C#提供了标准查询运算符,例如我想选择专利一系列(pantents)中以年份19开头的专利,可以用如下语句: IEnumerable<Patent> pantent ...
- Kafka入门学习随记(二)
====Kafka消费者模型 参考博客:http://www.tuicool.com/articles/fI7J3m --分区消费模型 分区消费架构图 图中kafka集群有两台服务器(Server), ...
- UCOS2_STM32F1移植详细过程(四)
Ⅰ.概述 上一篇文章是讲述uC/OS-II Ports下面os_cpu_a.asm.os_cpu_c.c和os_cpu.h文件底层端口代码的移植(修改)和说明,接着上一篇文章来讲述关于UCOS移植应用 ...
- Web Design:给实验室UI们的一堂课(下)
[讲稿]From top to down,自顶向下哈,首部栏.导航栏之后一般是页面的主模块,也就是Body部分,这一块儿才是你网站的核心内容,文章.新闻.动态.数据.图表.相册等都是在这儿体现出来.在 ...
- Unity Scripting Tutorials 要点记录
(搬运自我在SegmentFault的博客) 这几天通过Unity官网的Unity Scripting Tutorials的视频学习Unity脚本,观看的过程中做了记录.现在,整理了一下笔记,供自己以 ...
- WPF.UIShell UIFramework之自定义窗口的深度技术 - 模态闪动(Blink)、窗口四边拖拽支持(WmNCHitTest)、自定义最大化位置和大小(WmGetMinMaxInfo)
无论是在工作和学习中使用WPF时,我们通常都会接触到CustomControl,今天我们就CustomWindow之后的一些边角技术进行探讨和剖析. 窗口(对话框)模态闪动(Blink) 自定义窗口的 ...
- webpack 学习笔记 02 快速入门
webpack 的目标 将依赖项分块,按需加载. 减少web app的初始加载时间. 使每一个静态集合都能够作为组件使用. 有能力集成第三方库,作为组件使用. 高度可配置化. 适用于大型项目. INS ...
- poj 1789 Truck History
题目连接 http://poj.org/problem?id=1789 Truck History Description Advanced Cargo Movement, Ltd. uses tru ...
- django-pagination的使用
1.安装django-pagination 2.将文件夹pagination复制到项目的根目录下 3.修改settings: 1.将 'pagination.middleware.Pagination ...