hdu 1533 Going Home 最小费用最大流 入门题
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3125 Accepted Submission(s): 1590
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 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.
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
2
10
28
题意:把H和m一一配对。他们所需走的最小步数和 为多少。
做法:用bfs 先找出 随意 H 和 m 直接的最小步数。记录下来。 然后像二分图一样建图。 起点到 全部home 流量1,费用0。 home 和man 之间的费用为距离,流量1,man和终点ee之间流量1,费用0。 建图完。然后用最小费用最大流 跑一边就ok了。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
#include <stdlib.h>
#include <queue>
#include <map>
#include <algorithm>
using namespace std; const int MAXN = 10100;
const int MAXM = 30000000;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow,cost;
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1
void init(int n)
{
N = n;
tol = 0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost)
{
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = 0;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = 0;
edge[tol].cost = -cost;
edge[tol].flow = 0;
edge[tol].next = head[v];
head[v] = tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i = 0;i < N;i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -1;i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow &&
dis[v] > dis[u] + edge[i].cost )
{
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -1)return false;
else return true;
}
//返回的是最大流。 cost存的是最小费用
int minCostMaxflow(int s,int t,int &cost)
{
int flow = 0;
cost = 0;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
{
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
{
edge[i].flow += Min;
edge[i^1].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
} int n,m;
struct node
{
int x,y,bu;
};
//addedge(int u,int v,int cap,int cost)
char mp[110][110];//地图
char num[110][110];//点查 号
int mp_dis[110][110];//号 号距离 前 home 后 men
int mp_vis[110][110];
int dir[4][2]={1,0,0,1,0,-1,-1,0};
void bfs(int x,int y)
{
memset(mp_vis,-1,sizeof mp_vis);
queue<node> q;
node sta,nw,tem;
sta.bu=0;
sta.x=x;
sta.y=y;
q.push(sta); while(!q.empty())
{
nw=q.front();
q.pop();
if(mp[nw.x][nw.y]=='m')
mp_dis[num[x][y]][num[nw.x][nw.y]]=nw.bu;
for(int i=0;i<4;i++)
{
int xx=nw.x+dir[i][0];
int yy=nw.y+dir[i][1];
if(xx<0||xx>=n||yy<0||yy>=m)
continue;
if(mp_vis[xx][yy]!=-1&&nw.bu+1>=mp_vis[xx][yy])
continue;
tem.x=xx;
tem.y=yy;
mp_vis[xx][yy]=tem.bu=nw.bu+1;
q.push(tem);
}
}
} int main()
{
while(cin>>n>>m,n||m)
{
for(int i=0;i<n;i++)
{
scanf("%s",mp[i]);
}
int home,man;
home=man=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='H')
num[i][j]=home++;
if(mp[i][j]=='m')
num[i][j]=man++;
}
} for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='H')
bfs(i,j); }
}
int ss=home+man;
int ee=home+man+1;
init(home+man+2); for(int i=0;i<home;i++)
{
for(int j=0;j<man;j++)
{
addedge(i,home+j,1,mp_dis[i][j]);
}
} for(int i=0;i<home;i++)
addedge(ss,i,1,0);
for(int i=0;i<man;i++)
addedge(home+i,ee,1,0); /*
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{ printf("%c%d ",mp[i][j],num[i][j]);
}
puts("");
} for(int i=0;i<home;i++)
{
for(int j=0;j<man;j++)
{
printf("%d ",mp_dis[i][j]);
}
puts("");
}
*/
int ans;
minCostMaxflow(ss,ee,ans); printf("%d\n",ans); }
return 0;
} /*
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
*/
hdu 1533 Going Home 最小费用最大流 入门题的更多相关文章
- 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 ...
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- POJ 2135 最小费用最大流 入门题
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19207 Accepted: 7441 Descri ...
- hdu 1533 Going Home 最小费用最大流 (模板题)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- 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 ...
随机推荐
- 20180929 北京大学 人工智能实践:Tensorflow笔记05
(完)
- HBase 1.1.2 优化插入 Region预分配
预分Region 与 不预分Region 的测试: 1 不预分Region: 23~29秒插入100W数据 并且蛋疼的是每次都写入一个 RegionServer 且 只在一个 Reg ...
- KVM硬件辅助虚拟化之 EPT in Nested Virtualization
在嵌套虚拟环境(Nested Virtualization)下,执行在hypervisor上的Virtual Machine仍能够作为hypervisor去执行其他的Virutal Machine,而 ...
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list 最长回文 ...
- Ubuntu14环境下minigui安装问题记录--object.lo错误
minigui3.0.12在Ubuntu14上面编译只是去?出现这个错误:object.h:275:9: error: incompatible types when assigning to typ ...
- 关于APP上架制作二维码相关
1.安卓版本APP上架并生成二维码问题:安卓版本上架国内市场,这个情况比较复杂一些,比如百度,网址是以上传APP生成的一个编号来进行的,每次升级更新后都发生了变化,也就相当于每次升级后网址发生改变(比 ...
- Java中二进制字节与十六进制互转
在Java中字节与十六进制的相互转换主要思想有两点: 1.二进制字节转十六进制时,将字节高位与0xF0做"&"操作,然后再左移4位,得到字节高位的十六进制A;将字节低位与0 ...
- BZOJ 4385 单调队列
思路: 对于每一个r 要找最小的符合条件的l最优 这时候就要找在这个区间中 d长度的和的最大值 用单调队列更新就好了 //By SiriusRen #include <cstdio> #i ...
- js sort()函数 排序问题 var arr =['A-1-5-1','A-1-10-2','A-1-5-5','B-2-3-1','C-4-10-1'], 对这个数组进行排序,想达到的效果是["A-1-5-1", "A-1-5-5", "A-4-10-1", "A-1-10-2", "A-2-3-1"]
先介绍个方法 charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. stringObject.charCodeAt(index) ...
- @Mapper 和 @MapperScan 区别
1.@Mapper : 为了使接口被其他类引用,需要使用@Mapper注解,这种方式要求每一个mapper类都需要添加此注解,麻烦. package com.example.demo.dao; imp ...