Going Home(最小费用最大流)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 16200 | Accepted: 8283 |
Description
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.
Input
Output
Sample Input
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
Sample Output
2
10
28 改了一上午也没出结果,后来又重写了一遍才对,手误啊。
题意:一个n*m的矩阵,其中每个'm'代表一个人,每个‘H'代表一个房子,且人和房子的数目相同,要求每个人找到一个属于自己的房子,每个房子只能住一个人,人到房子的花费就是它们之间的曼哈顿距离。问他们的最小花费。 思路: 最小费用最大流问题,先建图:
建立一个超级源点s和一个超级汇点t.
s 指向所有的人,容量为1,费用为0;
每个人指向所有的房子,容量为1,费用为人和房子的曼哈顿距离;
所有房子指向t,容量为1,费用为0。
从源点到汇点求费用流。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int INF = 0x3f3f3f3f;
const int maxn = ;
struct node
{
int x,y;
}man[maxn],house[maxn];
int man_num,house_num;
int flow[maxn][maxn];
int cost[maxn][maxn];
int dis[maxn],parent[maxn];
int s,t;
int mincost; void spfa()
{
queue<int> que;
int inque[maxn];
while(!que.empty())
que.pop();
for(int i = s; i <= t; i++)
dis[i] = INF;
memset(inque,,sizeof(inque));
memset(parent,-,sizeof(parent)); que.push(s);
inque[s] = ;
dis[s] = ;
while(!que.empty())
{
int u = que.front();
que.pop();
inque[u] = ; for(int v = s; v <= t; v++)
{
if(flow[u][v] && dis[v] > dis[u] + cost[u][v])
{
dis[v] = dis[u] + cost[u][v];
parent[v] = u;
if(!inque[v])
{
inque[v] = ;
que.push(v);
}
}
}
}
} void MCMF()
{
mincost = ;
while()
{
spfa();//spfa在残量网络中找s-t最短路;
if(parent[t] == -) break;//若汇点不可达,表明当前流已是最小费用最大流。 for(int u = t; u != s; u = parent[u])//增广
{
flow[parent[u]][u] -= ;
flow[u][parent[u]] += ;
}
mincost += dis[t];//更新总费用;
}
} int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
if(n == && m == ) break;
getchar();
char str[];
man_num = ;
house_num = ; for(int i = ; i <= n; i++)
{
scanf("%s",str);
for(int j = ; str[j]; j++)
{
if(str[j] == 'm')
{
man[man_num].x = i;
man[man_num++].y = j+;
}
else if(str[j] == 'H')
{
house[house_num].x = i;
house[house_num++].y = j+;
}
}
}
memset(flow,,sizeof(flow));
memset(cost,,sizeof(cost));
s = ;//源点
t = man_num+house_num+;//汇点
for(int i = ; i < man_num; i++)
flow[s][i+] = ;//源点到所有人的容量为1
for(int i = ; i < man_num; i++)
{
for(int j = ; j < house_num; j++)
{
//每个人到所有房子的容量为1,费用为其曼哈顿距离;
flow[i+][j++man_num] = ;
cost[i+][j++man_num] = abs(man[i].x-house[j].x) + abs(man[i].y-house[j].y);
cost[j++man_num][i+] = -cost[i+][j++man_num];
}
}
for(int i = ; i < house_num; i++)
flow[i++man_num][t] = ;//所有房子到汇点的容量为1
MCMF();
printf("%d\n",mincost);
}
return ;
}
Going Home(最小费用最大流)的更多相关文章
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- bzoj1927最小费用最大流
其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→ =_=你TM逗我 刚要删突然感觉dinic的模 ...
- ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)
将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...
- HDU5900 QSC and Master(区间DP + 最小费用最大流)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...
- P3381 【模板】最小费用最大流
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...
- 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 821 Solved: 502[Submit][Status ...
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙, 每个逮捕队伍在每个城市可以选 ...
- UVa11082 Matrix Decompressing(最小费用最大流)
题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...
- UVa12092 Paint the Roads(最小费用最大流)
题目大概说一个n个点m条带权有向边的图,要给边染色,染色的边形成若干个回路且每个点都恰好属于其中k个回路.问最少要染多少边权和的路. 一个回路里面各个点的入度=出度=1,那么可以猜想知道各个点如果都恰 ...
- POJ3686 The Windy's(最小费用最大流)
题目大概说要用m个工厂生产n个玩具,第i个玩具在第j个工厂生产要Zij的时间,一个工厂同一时间只能生成一个玩具,问最少的用时. 这题建的图不是很直观.. 源点向玩具连容量1费用0的边 将每个工厂拆成n ...
随机推荐
- IOS-tableViewCell重用机制
IOS-tableViewCell重用机制 首先介绍tableViewCell原生cell的使用和重用机制 使用dequeueReusableCellWithIdentifier方法,这个方法会从缓存 ...
- 关于text-align无法居中的问题
昨天项目,一直出现一个无法居中的问题,最后发现竟然是text-align的问题,才发现自己对text-align的理解还是不够透彻,于是在此再举例分析下. css中的元素一共有三类:块元素.行内块和内 ...
- 好用的log
Log.getStackTraceString(new Throwable())
- 如何使用Jquery获取Form表单中被选中的radio值
$("input[name='opType']:checked").val() -------此方法估计用的比较多,通俗易懂 $("input:radio:checke ...
- 自己写的自动生成动态边框的jquery小插件
思路就是在元素四周添加<ul>列表,然后周期性地改变它的颜色,实现动态的效果,不支持ie7.ie8 预览链接http://gorey.sinaapp.com/myBorder/border ...
- angularjs kindEditor 中自定义按钮 弹出dialog
1.angular-kindeditor.js 第38行左右加 editorConfig.items = ["placehoder"]; 2.en.js 第234行 placeho ...
- Android Parcelable Trans byte[]
思路: http://stackoverflow.com/questions/10898116/make-custom-parcelable-containing-byte-array 谢谢, 这位外 ...
- Oracle dblink 使用详解
1.dblink简介 dblink(Database Link)数据库链接就是数据库的链接,跨本地数据库 2.使用语法详解 基本语法 CREATE [SHARED][PUBLIC] database ...
- healthkit 记录每天用户的运动情况
//详细操作步骤 http://www.csdn.net/article/2015-01-23/2823686-healthkit-tutorial-with-swift //官方api https: ...
- C#堆栈原理(我有两个例子测试你到底会不会)
背景 上次写了一篇文章关于try finnally的一些疑问(被我用windows live覆盖了,草),后来经过大神们解释,我明白了在我理解了try.finnally运行原理后,还欠缺的就是关于值类 ...