POJ 2195 D - Going Home 费用流
D - Going Home
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88038#problem/D
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
X D
Sample Output
2
10
28
HINT
题意
有一个图,图里面h表示人,m表示房间,每一个人需要滚回一个房间,每个人走一步需要1的花费
问你最小花费,使得每个人都走到不同的房间
题解:
偶的代码是抄的,所以直接看这儿吧:http://blog.csdn.net/u012860063/article/details/41792973
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow, cost;
int x, y;
} edge[MAXM],HH[MAXN],MM[MAXN];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N, M;
char map[MAXN][MAXN];
void init()
{
N = MAXN;
tol = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int cap, int cost)//左端点,右端点,容量,花费
{
edge[tol]. to = v;
edge[tol]. cap = cap;
edge[tol]. cost = cost;
edge[tol]. flow = ;
edge[tol]. next = head[u];
head[u] = tol++;
edge[tol]. to = u;
edge[tol]. cap = ;
edge[tol]. cost = -cost;
edge[tol]. flow = ;
edge[tol]. next = head[v];
head[v] = tol++;
}
bool spfa(int s, int t)
{
queue<int>q;
for(int i = ; i < N; i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -; i = edge[i]. next)
{
int v = edge[i]. to;
if(edge[i]. cap > edge[i]. flow &&
dis[v] > dis[u] + edge[i]. cost )
{
dis[v] = dis[u] + edge[i]. cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -) return false;
else return true;
}
//返回的是最大流, cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{
int flow = ;
cost = ;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t]; i != -; i = pre[edge[i^]. to])
{
if(Min > edge[i]. cap - edge[i]. flow)
Min = edge[i]. cap - edge[i]. flow;
}
for(int i = pre[t]; i != -; i = pre[edge[i^]. to])
{
edge[i]. flow += Min;
edge[i^]. flow -= Min;
cost += edge[i]. cost * Min;
}
flow += Min;
}
return flow;
} int main()
{
int n, m;
while(~scanf("%d%d",&n,&m))
{
if(n== && m==)
break;
int ch = , cm = ;
init();//注意
for(int i = ; i < n; i++)
{
scanf("%s",map[i]);
for(int j = ; j < m; j++)
{
if(map[i][j]=='H')
{
HH[ch].x = i;
HH[ch++].y = j;
}
else if(map[i][j]=='m')
{
MM[cm].x = i;
MM[cm++].y = j;
}
}
}
//printf("ch:%d cm:%d\n",ch,cm);
int beg = ;//超级起点
int end = *ch+;//超级汇点
for(int i = ; i < cm; i++)
{
addedge(beg,i+,,);//超级起点,容量为1,花费为0
for(int j = ; j < ch; j++)
{
int tt = abs(HH[i].x-MM[j].x)+abs(HH[i].y-MM[j].y);
//printf("tt:%d\n",tt);
addedge(i+,j++ch,,tt);
}
addedge(i++ch,end,,);//超级汇点容量为1,花费为0
}
int ans = ;
minCostMaxflow(beg,end,ans);
printf("%d\n",ans);
}
return ;
}
POJ 2195 D - Going Home 费用流的更多相关文章
- POJ 2195 Going Home(费用流)
http://poj.org/problem?id=2195 题意: 在一个网格地图上,有n个小人和n栋房子.在每个时间单位内,每个小人可以往水平方向或垂直方向上移动一步,走到相邻的方格中.对每个小人 ...
- POJ 2195 Going Home 最小费用最大流 尼玛,心累
D - Going Home Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- POJ 2135 Farm Tour (费用流)
[题目链接] http://poj.org/problem?id=2135 [题目大意] 有一张无向图,求从1到n然后又回来的最短路 同一条路只能走一次 [题解] 题目等价于求从1到n的两条路,使得两 ...
- 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(最小费用最大流)
题目:http://poj.org/problem?id=2195 有若干个人和若干个房子在一个给定网格中,每人走一个都要一定花费,每个房子只能容纳一人,现要求让所有人进入房子,且总花费最小. 构造一 ...
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- poj - 2195 Going Home (费用流 || 最佳匹配)
http://poj.org/problem?id=2195 对km算法不理解,模板用的也不好. 下面是大神的解释. KM算法的要点是在相等子图中寻找完备匹配,其正确性的基石是:任何一个匹配的权值之和 ...
- POJ 2195 Going Home / HDU 1533(最小费用最大流模板)
题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...
- POJ 2195 Going Home (费用流)
题面 On a grid map there are n little men and n houses. In each unit time, every little man can move o ...
随机推荐
- C#中的lock关键字
前几天与同事激烈讨论了一下,有一点收获,记录起来. 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. ...
- C++ 函数重载与函数匹配
<C++ Primer>笔记,整理关于函数重载与函数匹配的笔记. 函数重载 void func(int a); //原函数 void func(double a); //正确:形参类型不同 ...
- POJ 1423 Big Number
题意:求n阶乘的位数. 解法:斯特林公式,,然后取log10就是位数了,因为精度问题需要化简这个式子,特判1. 代码: #include<stdio.h> #include<iost ...
- [Papers]NSE, $\n u_3$, Lebesgue space, [Pokorny, EJDE, 2003; Zhou, MAA, 2002]
$$\bex \n u_3\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=\frac{3}{2},\quad 2\leq q\leq \i ...
- codeforces 678E Another Sith Tournament 概率dp
奉上官方题解 然后直接写的记忆化搜索 #include <cstdio> #include <iostream> #include <ctime> #include ...
- selenium打开带有扩展的chrome
每当用跑用例失败的时候,第一反应就是查看元素定位是不是正确,帮助定位的扩展是必不可少的,但是selenium一般打开的是不带扩展的干净的浏览器,如果操作步骤很长的话,就得手动去执行直到那一步去检查元素 ...
- 在Lua里写unity游戏笔记
gameobject.GetComponent<Transform>(); 翻译成Lua: gameObject:GetComponent (luanet.ctype (Transform ...
- Android和iOS隐藏状态条
Android: 在 AndroidManifest.xml 里 <activity android:theme="@android:style/Theme.NoTitleBar.Fu ...
- Oracle数据库管理之创建和删除数据库
转自:http://supportopensource.iteye.com/blog/678898 一.数据库管理概述 在完成Oracle软件安装后,DBA就应该对组织和管理数据库负责任,其主要任务是 ...
- 一个谷粉和3年的Google Reader重度使用者的碎碎念
2013-03-14 上午看到Andy Rubin辞去Android业务主管职务.由Chrome及应用高级副总裁继任的新闻,还在想这会给Android带来什么,中午刷微博的时候就挨了当头一棒:Goog ...