图论--网络流--费用流POJ 2195 Going Home
Description
On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every 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.
Input
There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing the 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.
Output
For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.
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
就是普通的费用流问题, 源点s编号0, 人编号1到n, 房子编号n+1到n+n, 汇点编号t, 源点s到每个人i有边(s, i, 1,0), 每个人i到每个房子j有边(i, j, 1, i人到j房的开销), 每个房子j到汇点t有边(j, t, 1, 0)。就成了最基本的费用流。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<cmath>
#define INF 1e9
using namespace std;
const int maxn=200+5;
struct Edge
{
int from,to,cap,flow,cost;
Edge(){}
Edge(int f,int t,int c,int fl,int co):from(f),to(t),cap(c),flow(fl),cost(co){}
};
struct MCMF
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
void init(int n,int s,int t)
{
this->n=n, this->s=s, this->t=t;
edges.clear();
for(int i=0;i<n;++i) G[i].clear();
}
void AddEdge(int from,int to,int cap,int cost)
{
edges.push_back(Edge(from,to,cap,0,cost));
edges.push_back(Edge(to,from,0,0,-cost));
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BellmanFord(int &flow,int &cost)
{
for(int i=0;i<n;++i) d[i]=INF;
queue<int> Q;
memset(inq,0,sizeof(inq));
d[s]=0, Q.push(s), a[s]=INF, p[s]=0, inq[s]=true;
while(!Q.empty())
{
int u=Q.front(); Q.pop();
inq[u]=false;
for(int i=0;i<G[u].size();++i)
{
Edge &e=edges[G[u][i]];
if(e.cap>e.flow && d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to]){ Q.push(e.to); inq[e.to]=true; }
}
}
}
if(d[t]==INF) return false;
flow +=a[t];
cost +=a[t]*d[t];
int u=t;
while(u!=s)
{
edges[p[u]].flow +=a[t];
edges[p[u]^1].flow -=a[t];
u=edges[p[u]].from;
}
return true;
}
int solve()
{
int flow=0,cost=0;
while(BellmanFord(flow,cost));
return cost;
}
}MM;
struct Node
{
int x,y;
Node(){}
Node(int x,int y):x(x),y(y){}
int get_dist(Node& b)
{
return abs(x-b.x)+abs(y-b.y);
}
}node1[maxn],node2[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==2 && n)
{
int num1=0,num2=0;//记录人数和房子数
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
char ch;
scanf(" %c",&ch);
if(ch=='m') node1[num1++]=Node(i,j);
else if(ch=='H') node2[num2++]=Node(i,j);
}
int src=0,dst=num1*2+1;
MM.init(num1*2+2,src,dst);
for(int i=1;i<=num1;++i)
{
MM.AddEdge(src,i,1,0);
MM.AddEdge(num1+i,dst,1,0);
for(int j=1;j<=num1;++j)
{
MM.AddEdge(i,num1+j,1,node1[i-1].get_dist(node2[j-1]));
}
}
printf("%d\n",MM.solve());
}
return 0;
}
图论--网络流--费用流POJ 2195 Going Home的更多相关文章
- 图论--网络流--费用流--POJ 2156 Minimum Cost
Description Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his s ...
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
- 图论--网络流--最大流--POJ 1698 Alice's Chance
Description Alice, a charming girl, have been dreaming of being a movie star for long. Her chances w ...
- 图论--网络流--最大流 POJ 2289 Jamie's Contact Groups (二分+限流建图)
Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very ...
- 图论-zkw费用流
图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...
- BZOJ2055 80人环游世界 网络流 费用流 有源汇有上下界的费用流
https://darkbzoj.cf/problem/2055 https://blog.csdn.net/Clove_unique/article/details/54864211 ←对有上下界费 ...
- 图论:费用流-SPFA+EK
利用SPFA+EK算法解决费用流问题 例题不够裸,但是还是很有说服力的,这里以Codevs1227的方格取数2为例子来介绍费用流问题 这个题难点在建图上,我感觉以后还要把网络流建模想明白才能下手去做这 ...
- 【上下界网络流 费用流】bzoj2055: 80人环游世界
EK费用流居然写错了…… Description 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么 一个80人的团 ...
- POJ训练计划3422_Kaka's Matrix Travels(网络流/费用流)
解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次仅仅能向右和向下走,走到一个格子上加上格子的数,能够走k次.问最大的和是多少. 思路: 建图:每一个格子掰成两个点,分别叫" ...
随机推荐
- python通俗讲解闭包
通俗理解闭包 先来看看什么是闭包吧 闭包是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合 ...
- MySQL入门,第五部分,表结构的修改
ALTER TABLE <基本表名> [ ADD <新列名> <列数据类型> [列完整性约束] DROP COLUMN <列名> MODIFY < ...
- "六号标题"组件:<h6> —— 快应用组件库H-UI
 <import name="h6" src="../Common/ui/h-ui/text/c_h6"></import> < ...
- Windows Server 2016 Storage Replication
Storage Replication是Windows Server 2016中新增的一项功能,它是利用windows server自带的块存储复制技术 首先,我们简答粗暴的交代一下部署需求: 1.该 ...
- AJ学IOS(23)UI之控制器管理
AJ分享,必须精品 控制器以及view的多种创建方式 控制器view的加载 通过storyboard创建 1:先加载storyboard⽂件(Test是storyboard的⽂文件名) UIStory ...
- echarts多个数据添加多个纵坐标
在我们echarts开发中,肯定会遇到一个问题.那就是当有多个数据且数据大小差距太大时,就会出现有些数据小到看不到的情况.所以在遇到这种情况时,我通常的解决办法就是给他多加一个坐标轴. option ...
- 【python】显示图片 并随意缩放图片大小 图片归一化
cv2.namedWindow("image_",0) cv2.imshow("image_",image)就可以随意缩放显示图片的窗口大小啦. ------ ...
- 挑战全网最幽默的Vuex系列教程:第三讲 Vuex旗下的Mutation
写在前面 上一讲「Vuex 旗下的 State 和 Getter」,告诉了我们怎么去使用仓库 store 中的状态数据.当然,光会用肯定还不够,大部分的应用场景还得对这些状态进行操控,那么具体如何操控 ...
- orcale 树形结构查询
接到需求是要在一个表中(表结构为主键id和父id)循环显示数据,类似于省市县++这种情况 也可能不只有三级子菜单 id name parentid 1 a 0 2 ...
- 2019-2020-1 20199310《Linux内核原理与分析》第十一周作业
1.问题描述 在一个capability系统中,当一个程序运行时,对应的线程会初始化一系列capabilities(令牌).当线程尝试访问某个对象时,操作系统会检查该线程的capabilities,并 ...