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 ...
随机推荐
- UVALive 5790 Ball Stacking DP
DP的方向真的很重要,这题做的时候死活想不出来,看了题解以后恍然大悟原来这么简单. 题意: 有n层堆成金字塔状的球,若你要选一个球,你必须把它上面那两个球取了,当然也可以一个不取.求选的球最大的权值和 ...
- Magento--判断checkout中是否使用了coupon code
在checkout页面中,如果想判断顾客是否有使用coupon code,可以通过checkout session来进行判断.以下代码会返回checkout中使用的coupon code或者返回空(当 ...
- BZOJ 3224 平衡树模板题
Treap: //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int n, ...
- HDU 4358 Boring counting dfs序+莫队算法
题意:N个节点的有根树,每个节点有一个weight.有Q个查询,问在以u为根的子树中,有恰好出现了K次的weight有多少种. 这是第一次写莫队算法,之前也只是偶有耳闻. 看了别人的代码打的,还是贴上 ...
- LDAP实现企业异构平台的统一认证
LDAP实现企业异构平台的统一认证 技术是为应用服务的,没有应用,技术就无用武之地.同样光配置完LDAP服务器没有任何意义,只有把所有需要认证的环节,只有纳入LDAP系统中,才能使它发挥应有 ...
- Cisco交换机端口安全
Cisco交换机端口安全 通过端口设置,可以限制允许访问交换机上某个端口的MAC地址以及IP(可选)来实现严格控制对该端口的输入,最终确保网络接入安全.配置网络安全时应该注意如下问题: 1 ...
- JS实现PC端全兼容复制
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- FreeBSD是UNIX系统的重要分支,其命令与Linux大部分通用,少部分是其特有。
FreeBSD是UNIX系统的重要分支,其命令与Linux大部分通用,少部分是其特有. 1: man 在线查询 man ls2: ls 查看目录与档案 ls -la3: ln 建立链接文件 ln -f ...
- Vue 全局过滤和局部过滤
局部过滤器(放在组件里) filters: { //局部过滤器 FormattingMoney:value=>{ return value==null? '0' : value/100 } }, ...
- 【Henu ACM Round#14 A】Vitaly and Night
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 连续两个如果不全是0就递增cnt [代码] #include <bits/stdc++.h> using namespa ...