hdu 1533(最小费用最大流)
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4223 Accepted Submission(s): 2178
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.
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
10
28
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = ;
const int N = ; ///most 100 person and house
const int M = N*N*;
struct Edge{
int u,v,cap,cost,next;
}edge[M];
int head[N],tot,low[N],pre[N];
int total ;
bool vis[N];
void addEdge(int u,int v,int cap,int cost,int &k){
edge[k].u=u,edge[k].v=v,edge[k].cap = cap,edge[k].cost = cost,edge[k].next = head[u],head[u] = k++;
edge[k].u=v,edge[k].v=u,edge[k].cap = ,edge[k].cost = -cost,edge[k].next = head[v],head[v] = k++;
}
void init(){
memset(head,-,sizeof(head));
tot = ;
}
bool spfa(int s,int t,int n){
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++){
low[i] = (i==s)?:INF;
pre[i] = -;
}
queue<int> q;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
if(edge[k].cap>&&low[v]>low[u]+edge[k].cost){
low[v] = low[u] + edge[k].cost;
pre[v] = k; ///v为终点对应的边
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t]==-) return false;
return true;
}
int MCMF(int s,int t,int n){
int mincost = ,minflow,flow=;
while(spfa(s,t,n))
{
minflow=INF+;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
minflow=min(minflow,edge[i].cap);
flow+=minflow;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
{
edge[i].cap-=minflow;
edge[i^].cap+=minflow;
}
mincost+=low[t]*minflow;
}
total=flow;
return mincost;
}
int n,m,a,b;
char graph[N][N];
struct House{
int x,y;
}h[N];
struct Person{
int x,y;
}p[N];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF,n+m){
init();
a=,b=;
for(int i=;i<n;i++){
scanf("%s",graph[i]);
for(int j=;j<m;j++){
if(graph[i][j]=='H'){
h[++a].x = i,h[a].y = j;
}
if(graph[i][j]=='m'){
p[++b].x = i,p[b].y = j;
}
}
}
int src = ,des = a+b+;
for(int i=;i<=a;i++){
for(int j=;j<=b;j++){
int D = abs(h[i].x-p[j].x)+abs(h[i].y-p[j].y);
addEdge(i,j+a,,D,tot);
}
}
for(int i=;i<=a;i++){
addEdge(src,i,,,tot);
}
for(int i=;i<=b;i++){
addEdge(i+a,des,,,tot);
}
int mincost = MCMF(src,des,a+b+);
printf("%d\n",mincost);
}
return ;
}
hdu 1533(最小费用最大流)的更多相关文章
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- HDU 1533 最小费用最大流(模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...
- hdu 4862KM&最小费用最大流
/*最小K路径覆盖的模型,用费用流或者KM算法解决, 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边, 流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1, 费用0,如果X ...
- hdu 3667(最小费用最大流+拆边)
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 6437 /// 最小费用最大流 负花费 SPFA模板
题目大意: 给定n,m,K,W 表示n个小时 m场电影(分为类型A.B) K个人 若某个人连续看了两场相同类型的电影则失去W 电影时间不能重叠 接下来给定m场电影的 s t w op 表示电影的 开始 ...
- hdu 4067(最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...
- hdu 2485(最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2485 思路:题目的意思是删除最少的点使1,n的最短路大于k.将点转化为边,容量为1,费用为0,然后就是 ...
- hdu 6201(最小费用最大流)
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- 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 ...
随机推荐
- Delight for a Cat
Time Limit: 1000 ms Memory Limit: 512 MB Description 从前,有一只懒猫叫CJB.每个小时,这只猫要么在睡觉,要么在吃东西,但不能一边睡觉一边吃东 ...
- 《python核心编程》读书笔记--第18章 多线程编程
18.1引言 在多线程(multithreaded,MT)出现之前,电脑程序的运行由一个执行序列组成.多线程对某些任务来说是最理想的.这些任务有以下特点:它们本质上就是异步的,需要多个并发事务,各个事 ...
- (转)Django发送html邮件
本文转自http://blog.csdn.net/yima1006/article/details/8991145 send_mail(subject, message, from_email, re ...
- JS开发中自定义调试信息开关
在开发过程中,可能随处留下几个console.log,或者alert语句,这些语句在开发过程中是很有价值的.但是项目一旦进入生产环境,过多的console.log可能影响到浏览器的运行效率,过多的al ...
- webstorm常用功能快捷方式
1 自动注释和撤销注释:ctrl+/ 在一句代码前面用 ctrl+/ 可以自动注释和撤销注释,js,html都可以,很好的省去了敲注释符的时间 (mac下为command+/,下同) 2 自动补全ht ...
- ZooKeeper食谱(八)
使用ZooKeeper构造高级别应用的指南 在这个文章中,你将会发现使用ZooKeeper来实现高级别功能的指南.所有的它们在客户端上被实现而不需要ZooKeeper特别的支持.希望社区将注意到这些约 ...
- 【JSP EL】EL表达式获取当前时间(两种方式)
第一种方式: //先在代码段定义<% long date = new Date().getTime(); request.setAttribute("date", date) ...
- LightOJ 1129 - Consistency Checker Trie树模板
题意:给出n条串判断是否存在一个串为另一个串的前缀. 思路:套Trie树的模板,先全部插入,再查找每个字串,如果查找字串完毕,但还存在下一个节点,说明存在前缀. /** @Date : 2016-11 ...
- [Luogu 2596] ZJOI2006 书架
[Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...
- 【poj3621】最优比率环
题意: 给定n个点,每个点有一个开心度F[i],每个点有m条单向边,每条边有一个长度d,要求一个环,使得它的 开心度的和/长度和 这个比值最大.n<=1000,m<=5000 题解: 最优 ...