POJ 2195 一人一房 最小费用流 建图 水题
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 21010 | Accepted: 10614 |
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
Source
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
const int N = 70;
const int M=10000+100;
struct edge{
int to,cap,cost,rev;
}; vector<edge> G[1005];
int dist[1005],inq[1005],prev[1005],prel[1005];
struct Point{
int x,y;
}; int n,m,x,y,c,cnth,cntm;
Point house[105],men[105]; void add_edge(int u,int v,int cap,int cost)
{
G[u].push_back(edge{v,cap,cost,G[v].size()});
G[v].push_back(edge{u,0,-cost,G[u].size()-1});
} int mincost(int s,int t,int f)
{
int ans=0;
while(f>0)
{
memset(dist,inf,sizeof(dist));
memset(inq,0,sizeof(inq));
dist[s]=0;
queue<int> q;
q.push(s);
inq[s]=1;
MM(prev,-1);
while(!q.empty())
{
int u=q.front();
q.pop();inq[u]=0;
for(int j=0;j<G[u].size();j++)
{
edge &e=G[u][j];
if(e.cap>0&&dist[e.to]>dist[u]+e.cost)
{
dist[e.to]=dist[u]+e.cost;
prev[e.to]=u;
prel[e.to]=j;
if(!inq[e.to])
{
q.push(e.to);
inq[e.to]=1;
}
}
}
}
for(int i=t;i>s;)
{
int f=prev[i];
if(f==-1) return -1;
int j=prel[i];
G[f][j].cap-=1;
G[i][G[f][j].rev].cap+=1;
ans+=G[f][j].cost;
i=prev[i];
}
f-=1;
}
return ans;
} void build()
{
for(int i=0;i<=cnth+cntm+1;i++) G[i].clear();
for(int i=1;i<=cntm;i++)
add_edge(0,i,1,0);
for(int i=1;i<=cnth;i++)
add_edge(cntm+i,cntm+cnth+1,1,0);
for(int i=1;i<=cntm;i++)
for(int j=1;j<=cnth;j++)
{
int dis=abs(house[j].x-men[i].x)+abs(house[j].y-men[i].y);
add_edge(i,j+cntm,1,dis);
}
} char s[105][105];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m)&&(n||m))
{
cnth=cntm=0;
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<m;j++)
if(s[i][j]=='H')
house[++cnth]=(Point){i,j+1};
else if(s[i][j]=='m')
men[++cntm]=(Point){i,j+1};
}
build();
printf("%d\n",mincost(0,cnth+cntm+1,cnth));
}
return 0;
}
分析:建图有一点点技术含量,人放左边,门放右边,加一个源点与汇点,然后跑一跑大小为人数(门数)的最小费用流就好,
POJ 2195 一人一房 最小费用流 建图 水题的更多相关文章
- poj 3281 Dining 网络流-最大流-建图的题
题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...
- POJ 2195 Going Home【最小费用流 二分图最优匹配】
题目大意:一个n*m的地图,上面有一些人man(m)和数量相等的house(H) 图上的距离为曼哈顿距离 问所有人住进一所房子(当然一个人住一间咯)距离之和最短是多少? 思路:一个人一间房,明显是二分 ...
- poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...
- POJ 2226 最小点覆盖(经典建图)
Muddy Fields Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8881 Accepted: 3300 Desc ...
- joj 2453 candy 网络流建图的题
Problem D: Candy As a teacher of a kindergarten, you have many things to do during a day, one of whi ...
- BZOJ 1303 CQOI2009 中位数图 水题
1303: [CQOI2009]中位数图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2340 Solved: 1464[Submit][Statu ...
- poj 2195 Going Home(最小费用流)
题目链接:http://poj.org/problem?id=2195 题目大意是给一张网格,网格中m代表人,h代表房子,网格中的房子和人数量相等,人可以向上向下走,每走1步花费加1,每个房子只能住一 ...
- POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)
/* bfs搜索!要注意的是点与点的权值是不一样的哦! 空地到空地的步数是1, 空地到墙的步数是2(轰一炮+移过去) 所以用到优先队列进行对当前节点步数的更新! */ #include<iost ...
- POJ 1161 Walls(Floyd , 建图)
题意: 给定n个城市, 然后城市之间会有长城相连, 长城之间会围成M个区域, 有L个vip(每个vip会处于一个城市里)要找一个区域聚会, 问一共最少跨越多少个长城. 分析: 其实这题难就难在建图, ...
随机推荐
- 索引及explain 详解
索引的分类: 普通索引:仅加速查询 唯一索引:加速查询 + 列值唯一(可以有null) 主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个 组合索引:多列值组成一个索引,专门用于组合 ...
- python 操作mongodb 文件相关
https://api.mongodb.com/python/current/tutorial.html# 文档地址 from pymongo import MongoClientfrom gridf ...
- JDBC1
---恢复内容开始--- create table `account` ( `id` ), `name` ), `balance` ) ); insert into `account` (`id`, ...
- 富文本编辑器--使用textarea即时更新文本域同步编辑器内容
使用 textarea wangEditor 从v3版本开始不支持 textarea ,但是可以通过onchange来实现 textarea 中提交富文本内容. <div id="di ...
- ubuntu自己定义环境变量,替代常用的操作命令
问题背景是这样的,因为自己会经常用自己的用户链接服务器,比如自己的用户是yongjie,然后服务器的ip是162.105.97.31 所以经常执行的命令是ssh yongjie@162.105.97. ...
- Mybatis常见面试题总结
1.#{}和${}的区别是什么? ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. ...
- 关于spring读取配置文件的两种方式
很多时候我们把需要随时调整的参数需要放在配置文件中单独进行读取,这就是软编码,相对于硬编码,软编码可以避免频繁修改类文件,频繁编译,必要时只需要用文本编辑器打开配置文件更改参数就行.但没有使用框架之前 ...
- Delphi 有类型文件
- Maven配置和使用
Eclipse下的Maven开发环境搭建. 现在要用到Eclipse开发Maven的项目,需要配置Maven,简单整理下配置方法. 1.下载Maven安装包,http://maven.apache.o ...
- linux版宝塔安装Redis
1安装服务 2配置设置 3安装PHP扩展 首先,我们来安装服务,进入管理面板--软件管理--运行环境--redis-点击安装,等待完成 完成之后开始第二步,配置设置.这一步根据自己需要进行配置.注意安 ...