hdoj--1533--Going Home(最小费用流)
Going Home
Total Submission(s): 3800 Accepted Submission(s): 1948
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.
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.
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
2
10
28
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 200+10
#define MAXM 80000+100
#define INF 0x3f3f3f
struct node
{
int from,to,cap,flow,cost,next;
}edge[MAXM];
int head[MAXN],top,pre[MAXN];
int dis[MAXN],vis[MAXN],n,m,source,sink;
void init()
{
top=0;
memset(head,-1,sizeof(head));
}
struct Node
{
int x,y;
};
Node H[MAXN],M[MAXN];
int m_cnt,h_cnt;
void add(int u,int v,int w,int c)
{
node E1={u,v,w,0,c,head[u]};
edge[top]=E1;
head[u]=top++;
node E2={v,u,0,0,-c,head[v]};
edge[top]=E2;
head[v]=top++;
}
int dist(int x1, int y1, int x2, int y2)
{
return abs(x1 - x2) + abs(y1 - y2);
}
void getmap()
{
m_cnt=h_cnt=0;
char str[110][110];
for(int i=0;i<n;i++)
{
scanf("%s",str[i]);
for(int j=0;j<m;j++)
{
if(str[i][j]=='m')
{
++m_cnt;
M[m_cnt].x=i;
M[m_cnt].y=j;
}
if(str[i][j]=='H')
{
h_cnt++;
H[h_cnt].x=i;
H[h_cnt].y=j;
}
}
}
int k=m_cnt;
source=0;
sink=2*k+1;
for(int i=1;i<=k;i++)
{
add(source,i,1,0);
add(i+k,sink,1,0);
for(int j=1;j<=k;j++)
{
int d=dist(H[i].x,H[i].y,M[j].x,M[j].y);
add(i,j+k,1,d);
}
}
}
bool SPFA(int s,int t)
{
queue<int>q;
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
dis[s]=0;
vis[s]=1;
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)
{
node E=edge[i];
if(dis[E.to]>dis[u]+E.cost&&E.cap>E.flow)
{
dis[E.to]=dis[u]+E.cost;
pre[E.to]=i;
if(!vis[E.to])
{
vis[E.to]=true;
q.push(E.to);
}
}
}
}
return pre[t]!=-1;
}
void MCMF(int s,int t,int &cost,int &flow)
{
flow=0;
cost=0;
while(SPFA(s,t))
{
int Min=INF;
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
node E=edge[i];
Min=min(Min,E.cap-E.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;
// printf("%d\n",cost);
}
}
int main()
{
while(scanf("%d%d",&n,&m),n|m)
{
init();
getmap();
int cost,flow;
MCMF(source,sink,cost,flow);
printf("%d\n",cost);
}
return 0;
}
hdoj--1533--Going Home(最小费用流)的更多相关文章
- 最大流增广路(KM算法) HDOJ 1533 Going Home
题目传送门 /* 最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法 */ #include <cstdio> #include <cmath> #incl ...
- HDU 4067 hdoj 4067 Random Maze 最小费用流
给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...
- hdu 1533 Going Home 最小费用流
构建地图非常easy bfs预处理地图.距离的成本 来源所有m建方,流程1费0 m所有H建方,流程1距离成本 H汇点建设成为各方.流程1费0 #include<cstdio> #inclu ...
- hdoj 1533 Going Home 【最小费用最大流】【KM入门题】
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- HDOJ的题目分类
模拟题, 枚举 1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 10 ...
- hdoj分类
http://blog.csdn.net/lyy289065406/article/details/6642573 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 ...
- HDOJ题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
- HDU——PKU题目分类
HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...
- [转] HDU 题目分类
转载来自:http://www.cppblog.com/acronix/archive/2010/09/24/127536.aspx 分类一: 基础题:1000.1001.1004.1005.1008 ...
- HDU ACM 题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
随机推荐
- 计算laws的matlab代码
很简单的代码:不过花了codeforge上的10个点,自己写也早写出来了; 代码如下: 文件:calLaws.m function [y,h_v,h_h]=calLaws(x,id,LocalEner ...
- (转)基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化
http://www.cnblogs.com/wuhuacong/p/4775282.html 在各种Web开发过程中,对话框和提示框的处理是很常见的一种界面处理技术,用得好,可以给用户很好的页面体验 ...
- POJ_2063_完全背包
Investment Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10090 Accepted: 3540 Descr ...
- C# 前一个数是后一个数的父级
private void button2_Click(object sender, EventArgs e) { var str = "1 2 3 4 5 6 7 8 9 10 11 12 ...
- HTTP 返回码中 301 与 302 的区别
转自:http://blog.csdn.net/qmhball/article/details/7838989 一.官方说法301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之 ...
- python-flask-2 安装及设定 flask
https://linoxide.com/linux-how-to/install-flask-python-ubuntu/ 1. prerequisites > create a new us ...
- http://www.phplo.com/special/2013/0616/467.html
http://www.phplo.com/special/2013/0616/467.html
- web跨域通信问题解决
Web页面的跨域问题产生原因是企图使用JS脚本读写不同域的JS作用域.问题根源来自JavaScript的同源策略:出于安全考虑,Javascript限制来自不同源的web页面JS脚本之间进行交互.否则 ...
- HDU 4456 Crowd
Crowd Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 数位dp无前导零
题目链接:http:// www.lydsy.com/JudgeOnline/problem.php?id=1026 #include <iostream> #include < ...