POJ 2195 Going Home(最小费用最大流)
http://poj.org/problem?id=2195
题意 : N*M的点阵中,有N个人,N个房子。让x个人走到这x个房子中,只能上下左右走,每个人每走一步就花1美元,问当所有的人都归位了之后,需要花多少美元。
思路 :最小费用最大流。把人作为一个顶点集合U,房子作为另一个顶点集合V,把U中所有点到V中所有点连线,费用cost[u][v]为abs(△x)+abs(△y),反向弧费用cost[v][u]= -cost[u][v],容量cap[u][v]=1,构成一个多源多汇的二分图。 由于每一个多源多汇的网络流都必有一个与之对应的单源单汇的网络流,为了便于解题,由此构造一个超级源s和超级汇t,超级源s与U中所有点相连,费用cost[s][u]=0(这是显然的),容量cap[s][u]=1;V中所有点与超级汇t相连,费用cost[v][t]=0(这是显然的),容量cap[t][v]=1。至于其他不连通的点,费用与容量均为0。容量为0的边,可以理解为饱和边,不再连通。而上述的所有边之所以容量初始化为1,是因为每间房子只允许入住1个人。而与超级源(汇)相连的边的费用之所以为0,是为了现在所构造的单源单汇网络流最终所求的最小费用等于原来的多源多汇网络流的最小费用。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <math.h> using namespace std; const int maxn = ;
struct node
{
int u ;
int v ;
}p[],h[] ; int pre[maxn],dist[maxn],n,m,pn,hn,s,t,cnt;
int cap[maxn][maxn],flow[maxn][maxn],cost[maxn][maxn] ;
bool flag[maxn] ;
char ch[maxn][maxn] ; const int INF = ; void Init()
{
pn = hn = ;
cnt = s = ;
memset(cap,,sizeof(cap)) ;
memset(flow,,sizeof(flow)) ;
memset(cost,,sizeof(cost)) ;
}
void spfa()
{
queue<int>Q ;
for(int i = ; i < maxn ; i++)
dist[i] = INF ;
memset(pre,-,sizeof(pre)) ;
memset(flag,false,sizeof(flag)) ;
Q.push(s) ;
flag[s] = true ;
dist[s] = ;
while(!Q.empty())
{
int u = Q.front() ;
Q.pop() ;
flag[u] = false ;
for(int v = ; v <= t ; v++)
{
if(cap[u][v] && dist[v] > dist[u] + cost[u][v])
{
dist[v] = dist[u] + cost[u][v] ;
pre[v] = u ;
if(!flag[v])
{
Q.push(v) ;
flag[v] = true ;
}
}
}
}
} void mcmf()
{
for( ; ; )
{
spfa() ;
if(pre[t] == -) break ;//没有父节点了,
int x = t ,minn = INF ;
while(pre[x] != -)
{
minn = min(minn,cap[pre[x]][x]) ;
x = pre[x] ;
}
x = t ;
while(pre[x] != -)
{
cap[pre[x]][x] -= minn ;
cap[x][pre[x]] += minn ;
cnt += minn*cost[pre[x]][x];
x = pre[x];
}
} } int main()
{
while(scanf("%d %d",&n,&m) != EOF)
{
if(n == && m == ) break ;
Init() ;
for(int i = ; i < n ; i++)
{
scanf("%s",ch[i]) ;
for(int j = ; j < m ; j++)
{
if(ch[i][j] == 'H')
{
h[++hn].u = i ;
h[hn].v = j ;
}
else if(ch[i][j] == 'm')
{
p[++pn].u = i ;
p[pn].v = j ;
}
}
}
t = pn+hn+ ;
for(int i = ; i <= pn ; i++)
cap[s][i] = ;
for(int i = ; i <= hn ; i++)
cap[i+pn][t] = ;
for(int i = ; i <= pn ; i++)
{
for(int j = ; j <= hn ; j++)
{
cap[i][j+pn] = ;
cost[i][j+pn] = fabs(p[i].u-h[j].u) + fabs(p[i].v-h[j].v) ;
cost[j+pn][i] = -cost[i][j+pn] ;
}
}
mcmf() ;
printf("%d\n",cnt) ;
}
return ;
}
POJ 2195 Going Home(最小费用最大流)的更多相关文章
- POJ 2195 - Going Home - [最小费用最大流][MCMF模板]
题目链接:http://poj.org/problem?id=2195 Time Limit: 1000MS Memory Limit: 65536K Description On a grid ma ...
- POJ 2195 Going Home 最小费用最大流 尼玛,心累
D - Going Home Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- poj 2195 Going Home(最小费用最大流)
题目:http://poj.org/problem?id=2195 有若干个人和若干个房子在一个给定网格中,每人走一个都要一定花费,每个房子只能容纳一人,现要求让所有人进入房子,且总花费最小. 构造一 ...
- poj 2351 Farm Tour (最小费用最大流)
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17230 Accepted: 6647 Descri ...
- POJ 2157 Evacuation Plan [最小费用最大流][消圈算法]
---恢复内容开始--- 题意略. 这题在poj直接求最小费用会超时,但是题意也没说要求最优解. 根据线圈定理,如果一个跑完最费用流的残余网络中存在负权环,那么顺着这个负权环跑流量为1那么会得到更小的 ...
- poj 2135 Farm Tour 最小费用最大流建图跑最短路
题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...
- POJ 3680: Intervals【最小费用最大流】
题目大意:你有N个开区间,每个区间有个重量wi,你要选择一些区间,使得满足:每个点被不超过K个区间覆盖的前提下,重量最大 思路:感觉是很好想的费用流,把每个区间首尾相连,费用为该区间的重量的相反数(由 ...
- POJ 2135 Farm Tour [最小费用最大流]
题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很 ...
- [poj] 1235 Farm Tour || 最小费用最大流
原题 费用流板子题. 费用流与最大流的区别就是把bfs改为spfa,dfs时把按deep搜索改成按最短路搜索即可 #include<cstdio> #include<queue> ...
- POJ 2516 Minimum Cost [最小费用最大流]
题意略: 思路: 这题比较坑的地方是把每种货物单独建图分开算就ok了. #include<stdio.h> #include<queue> #define MAXN 500 # ...
随机推荐
- 까페24 호스팅 php 에러메세지 출력
[문제점] 최근 까페24호스팅에서 php작업시화면에 에러메세지가 나오지 않아 디버깅시에 매우 곤란함 [해결책] .htaccess 내용에 아래추가.=================== ...
- orcale授权
grant connect,resource,dba to 表名;--用户授权 CONNECT角色: --是授予最终用户的典型权利,最基本的 CREATE SESSION --建立会话 RESOURC ...
- ASPxGridView动态创建表格列编辑模板
在项目中用到了DevExpress的ASPxGridview控件,每每去配置它的时候,总感觉很是啰嗦,于是想到了用代码自动配置. 于是有了这样的代码: foreach (ZiyuWeb.Entity. ...
- android基本知识(一)
今天开始更新一下android的基本知识,下面是敲代码遇到的问题. 1)我们来谈谈android.intent.category.DEFAULT的用途. 在谈这个tag的用途之前,读者要明白什 ...
- WinForm程序中两份mdf文件问题的解决
在项目中用程序中嵌入mdf文件的方式来进行SQLServer数据库开发非常方便,用来发布开源项目等很方便,点击就可以运行,免部署,特别是在教学中用起来更加方便,老师不用先将数据库文件detach再发给 ...
- ios - cordova(phoneGap)
安装教程 下载 node.js. http://nodejs.org/ 下载后,直接安装就可以了. 安装 Cordova工具, $ sudo npm install -g cordova 创建APP: ...
- 在linux CentOS6上安装web环境
感谢浏览,欢迎交流=.= 都说linux作为服务器优于window,近期也是学习了下linux. win7下安装了linux虚拟机,购买linux阿里云主机,开启linux之旅. 进入正题,在linu ...
- 腾讯视频嵌入手机端网站demo - 就像微信文章中一样一样的
页面中的调用如下: <iframe id="video_iframe" class="video_iframe" src="TenVideoPl ...
- “微信应用号对行业影响”之一,app开发速来围观
昨天,微信张小龙的一个讲话刷爆朋友圈,除了4大价值观,最后顺便提到:要推出微信应用号! 其实,价值观也就说说听听,最后顺便提到的微信应用号,才是真正的巨型炸弹. 腾讯挟6亿高粘度用户之重,号令天下,阿 ...
- PHP初学留神(二)
1.===比较运算符 记得上上篇中说过===与==的问题.当时说,===还要类型相同.但到底是怎样呢?因为我们知道比较运算符是可以把两个值类型转换的.举个栗子,如果一个数字和字符串比较,则字符串会转化 ...