hdu1533 Going Home 最小费用最大流 构造源点和汇点
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5504 Accepted Submission(s): 2890
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.
/**
题目:hdu1533 Going Home
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533
题意:n个人回到n个房子,每个房子只能住一个人。求最少花费。
思路:
构造一个源点,到达所有的人,cap = 1, cost = 0;
构造一个汇点,所有的房子到汇点,cap = 1, cost = 0;
所有的人到所有的房子,cap = 1, cost = 人到房子的最短距离。
然后最小费用最大流算法。
*/
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int N = ;
struct Edge{
int from, to, cap, flow, cost;
Edge(int u,int v,int c,int f,int cost):from(u),to(v),cap(c),flow(f),cost(cost){}
};
struct MCMF
{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[N];
int inq[N];
int d[N];
int p[N];
int a[N]; void init(int n)
{
this->n = n;
for(int i = ; i <= n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost){
edges.push_back((Edge){from,to,cap,,cost});
edges.push_back((Edge){to,from,,,-cost});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BellmanFord(int s,int t,int &flow,int &cost){
for(int i = ; i <= n; i++) d[i] = INF;
memset(inq, , sizeof inq);
d[s] = ; inq[s] = ; p[s] = ; a[s] = INF; queue<int> Q;
Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = ;
for(int i = ; i < G[u].size(); i++){
Edge& e = edges[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]){ Q.push(e.to); inq[e.to] = ;}
}
}
}
if(d[t]==INF) return false;
flow += a[t];
cost += d[t]*a[t];
int u = t;
while(u!=s){
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
u = edges[p[u]].from;
}
return true;
}
int Mincost(int s,int t)
{
int flow = , cost = ;
while(BellmanFord(s,t,flow,cost)) ;
return cost;
}
int dis(int x,int y,int xx,int yy)
{
return abs(x-xx)+abs(y-yy);
}
};
char s[N][N];
typedef pair<int,int> P;
vector<P> man;
vector<P> hou;
int main()
{
int n, m;
while(scanf("%d%d",&n,&m)==)
{
if(n==&&m==) break;
man.clear();
hou.clear();
for(int i = ; i < n; i++){
scanf("%s",s[i]);
for(int j = ; j < m; j++){
if(s[i][j]=='m'){
man.push_back(P(i,j));
}
if(s[i][j]=='H'){
hou.push_back(P(i,j));
}
}
}
MCMF mcmf;
mcmf.s = ;
mcmf.t = man.size()*+;
mcmf.init(mcmf.t);
for(int i = ; i < man.size(); i++){/// s->man
mcmf.AddEdge(mcmf.s,i+,,);
}
for(int i = ; i < hou.size(); i++){/// hou->t
mcmf.AddEdge(man.size()+i+,mcmf.t,,);
}
///man->hou
for(int i = ; i < man.size(); i++){
for(int j = ; j < hou.size(); j++){
int from, to, cap, cost;
from = i+;
to = man.size()+j+;
cap = ;
cost = mcmf.dis(man[i].first,man[i].second,hou[j].first,hou[j].second);
mcmf.AddEdge(from,to,cap,cost);
}
}
printf("%d\n",mcmf.Mincost(mcmf.s,mcmf.t));
}
return ;
}
hdu1533 Going Home 最小费用最大流 构造源点和汇点的更多相关文章
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- [hdu1533]二分图最大权匹配 || 最小费用最大流
题意:给一个n*m的地图,'m'表示人,'H'表示房子,求所有人都回到房子所走的距离之和的最小值(距离为曼哈顿距离). 思路:比较明显的二分图最大权匹配模型,将每个人向房子连一条边,边权为曼哈顿距离的 ...
- HIT2739 The Chinese Postman Problem(最小费用最大流)
题目大概说给一张有向图,要从0点出发返回0点且每条边至少都要走过一次,求走的最短路程. 经典的CPP问题,解法就是加边构造出欧拉回路,一个有向图存在欧拉回路的充分必要条件是基图连通且所有点入度等于出度 ...
- BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模
本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...
- 最小费用最大流 POJ2195-Going Home
网络流相关知识参考: http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 出处:優YoU http://blog.csdn. ...
- 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004
题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...
- POJ 2195 Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意 : N*M的点阵中,有N个人,N个房子.让x个人走到这x个房子中,只能上下左右走,每个人每走一步就花1美元,问当所有的人都归位了之 ...
- [BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
[Problem Description] 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队 ...
- POJ 3422 Kaka's Matrix Travels (最小费用最大流)
POJ 3422 Kaka's Matrix Travels 链接:http://poj.org/problem? id=3422 题意:有一个N*N的方格,每一个方格里面有一个数字.如今卡卡要从左上 ...
随机推荐
- Asp.Net MVC part4 异步、校验、区域Area
异步方式1:使用jquery的异步函数方式2:使用MVC的AjaxHelper行为的返回值设置:JsonResult对象,使用Json方法接收一个对象,在内部会完成对象的js序列化,向输出流中输出js ...
- Ubuntu 16.04通过源码安装QUEM虚拟机
下载编译安装: wget http://download.qemu-project.org/qemu-2.9.0.tar.xz tar xvJf qemu-2.9.0.tar.xz cd qemu-2 ...
- delphi报警声音 Beep、MessageBeep 和 Windows.Beep
转自:http://blog.csdn.net/yunqian09/article/details/5554527 我的办法,增加一个timer 设置间隔100ms,通过timer的使能否,控制报 ...
- 【k8s】了解一下k8s
了解一下k8s 地址: https://www.kubernetes.org.cn/doc-11
- redis_安装及使用
一.文档资料 1.官方网站:http://redis.io/ 2.官方文档:http://redis.io/documentation 3.常用命令文档:http: ...
- 引用日志log4net.dll的web.config配置
<configSections> <section name="log4net" type="log4net.Config.Log4NetConfigu ...
- Android性能调优篇之探索JVM内存分配
开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...
- Druid对比Cassandra
不是Cassandra专家, 如果描绘有错误, 请通过邮件列表或者其他方式告知, 我们会修正. Druid对扫描和聚合做了很大程度的优化, 不用提前计算就支持任意的向下钻取, 还可以实时摄入流式数据并 ...
- go 中的pacage 名称 和import {}中的名称
参考: https://groups.google.com/forum/#!topic/golang-nuts/oawcWAhO4Ow Hi, Nan Xiao <xiaona...@gmail ...
- docker入门——安装及简单操作
和安装其他软件一样,安装Docker也需要一些基本的前提条件.Docker要求的条件具体如下: 运行64位CPU构架的计算机(目前只能是x86_64和amd64),Docker目前不支持32位CPU. ...