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 ...
随机推荐
- Java设计模式05:常用设计模式之原型模式(创建型模式)
1. Java之原型模式(Prototype Pattern) 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. ...
- SQL Server中的20个系统变量
1.@@CONNECTIONS返回自上次启动 Microsoft SQL Server以来连接或试图连接的次数.示例:下面的示例显示了到当前日期和时间为止试图登录的次数.SELECT GETDATE( ...
- URAL 2032 - Conspiracy Theory and Rebranding【本源勾股数组】
[题意] 给出三角形的三个边长,均是10^7以内的整数,问三角形的三个角的坐标是否能均是整数,输出其中任意一个解. [题解] 一开始想的是枚举一条边的横坐标,然后通过勾股定理以及算角度求出其他点的坐标 ...
- Simple screenshot that explains the singleton invocation.
Here is the code: /* Some class,such as a config file,need to be only one.So we need to control the ...
- c# 左连接写法
var itemandformulas = from i in AttendanceItemList join f in AttendanceFormulaList on i.AttendanceCo ...
- shell脚本学习之case例子
case和select结构在技术上说并不是循环, 因为它们并不对可执行代码块进行迭代. 但是和循环相似的是, 它们也依靠在代码块顶部或底部的条件判断来决定程序的分支. 在代码块中控制程序分支 ca ...
- Typescript 团队合作的利器
前言 在介绍Typescript 之前,我需要隆重介绍一个人: 安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi ...
- 限制UITextField/UITextView的输入字数与中文输入之后的英文换行问题
要限制一个UITextField/UITextView的输入字数,首先想到的应该是通过UITextFieldDelegate/UITextViewDelegate的代理方法来限制,那么如何来更好的限制 ...
- 【POJ2912】【并查集】Rochambeau
Description N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is th ...
- Win异常: 除了chrome浏览器外,所有安装的软件都连不上网
经查找资料,是LSP被篡改,恢复后使用正常. 百度百科 LSP: Layered Service Provider, 即分层服务提程序,Winsock 作为应用程序的 Windows 的网络套接字工 ...