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的方格,每一个方格里面有一个数字.如今卡卡要从左上 ...
随机推荐
- Scala高手实战****第19课:Scala的包、继承覆写及Spark源码鉴赏
1.SparkSession.scala //导入某个类 import scala.beans.Introspector //导入某包下所有的类 import scala.beans._ //导入某包 ...
- 关于GIT的一些注意点
往空仓库提交代码之前先将文档区的_gitignore放到项目根目录然后改名成.gitignore然后git add .gitignore以上的目的是忽略一些不应该提交GIT的文件,多人编辑工程的时候不 ...
- windbg学习—-.ecxr
.ecxr 命令定位当前异常的上下文信息,并显示指定记录中的重要寄存器 0:000> .ecxr eax=10000000 ebx=7ffd9000 ecx=77386500 edx=002 ...
- 调试手机上网页 (断点 console timeline 选择dom)
用手机看网页,越来越多,手机app套个webview的也很多,那该如何调试手机上的页面了?比如 断点,选dom,console,控制台输出,查看内存,== 嗯,万能的的chrome和safari还是帮 ...
- mac 切换默认python版本
https://www.zhihu.com/question/30941329 首先终端的“python”命令会执行/usr/local/bin下的“python”链接,链接相当于win下的快捷方式, ...
- Widows 注册表 HKEY_CLASSES_ROOT
Widows 注册表 HKEY_CLASSES_ROOT在此关键字之下,可以看到有一个CLSID关键字.在CLSID关键字之下列有系统中安装的所有组件的CLSID.注册表CLSID是一个具有如下格式的 ...
- x-forwarded-for之深度挖掘
如今利用nginx做负载均衡的实例已经很多了,针对不同的应用场合,还有很多需要注意的地方,本文要说的就是在通过CDN 后到达nginx做负载均衡时请求头中的X-Forwarded-For项到底发生了什 ...
- Listener监听器之HttpSessionListener
编写一个OnlineUserListener. package anni; import java.util.List; import javax.servlet.ServletContext; im ...
- java中List和Array相互转换
List to Array List 提供了toArray的接口,所以可以直接调用转为object型数组 List<String> list = new ArrayList<Stri ...
- Django——META内部类选项
Django 模型类的Meta是一个内部类,它用于定义一些Django模型类的行为特性.以下对此作一总结: abstract 这个属性是定义当前的模型类是不是一个抽象类.所谓抽象类是不会对应 ...