题目大意:

有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子。每个房子只能进入一个人。

算法讨论:

注意是KM 和 MCMF算法,我写的是MCMF算法,一开始想的是连10000个点,但是不会连那些大众点之间的边,只会连超级点和普通点之间的边。后来觉得只要连房子点和

人点就可以了。连从人到房子的边,容量是1,花费是他们之间的曼哈顿距离,然后超级源点和超级汇点像上面那样连接,注意连点的时候把他们每个点都具体化一下,就是把点值

都精确到一个连续的范围内去。然后做从超级源点到超级汇点的MCMF算法就可以了。至于那10000个之间的连边,觉得虽然效率不高,但是还是有必要考虑一下。大家有知道的撒

告诉一下。感谢万分。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue> using namespace std; struct MCMF{
static const int N = * + ;
static const int M = * * + ;
static const int oo = 0x3f3f3f3f; int n, m, s, t, tot;
int first[N], next[M];
int u[M], v[M], cap[M], flow[M], cost[M];
int dis[N], a[N], inque[N], pre[N]; void Clear(){memset(first, -, sizeof first);tot = ;} void Add(int from, int to, int cp, int flw, int ct){
u[tot] = from; v[tot] = to; cap[tot] = cp; flow[tot] = ; cost[tot] = ct;
next[tot] = first[u[tot]];
first[u[tot]] = tot; ++ tot;
u[tot] = to; v[tot] = from; cap[tot] = ; flow[tot] = ; cost[tot] = -ct;
next[tot] = first[u[tot]];
first[u[tot]] = tot; ++ tot;
} bool bfs(int &flw, int &ct){
for(int i = ; i <= n + ; ++ i) dis[i] = oo;
memset(inque, , sizeof inque);
dis[s] = ; pre[s] = ; a[s] = oo; inque[s] = ; queue <int> q;
q.push(s);
while(!q.empty()){
int now = q.front(); q.pop();
inque[now] = ; for(int i = first[now]; i != -; i = next[i]){
if(cap[i] > flow[i] && dis[v[i]] > dis[now] + cost[i]){
dis[v[i]] = dis[now] + cost[i];
a[v[i]] = min(a[now], cap[i] - flow[i]);
pre[v[i]] = i;
if(!inque[v[i]]){
inque[v[i]] = ; q.push(v[i]);
}
}
}
} if(dis[t] == oo) return false;
flw += a[t];
ct += dis[t] * a[t]; int now = t;
while(now != s){
flow[pre[now]] += a[t];
flow[pre[now]^] -= a[t];
now = u[pre[now]];
}
return true;
} int MinCostMaxFlow(int s, int t){
this->s = s;this->t = t;
int flw = , ct = ;
while(bfs(flw, ct));
return ct;
}
}Net; struct Position{
int l, r, id;
Position(int _l=, int _r=, int _id=): l(_l), r(_r), id(_id){}
}mm[], HH[]; int ns, ms, cnt1, cnt2, tp1, tp2;
char str[][]; void Solve(){
for(int i = ; i <= tp1; ++ i){
for(int j = ; j <= tp2; ++ j){
int x1 = mm[i].l, y1 = mm[i].r;
int x2 = HH[j].l, y2 = HH[j].r;
Net.Add(mm[i].id, HH[j].id, , , abs(x1-x2) + abs(y1-y2));
}
}
} int main(){ while(scanf("%d%d", &ns, &ms) && ns && ms){
Net.Clear();
cnt1 = cnt2 = ;
tp1 = tp2 = ;
for(int i = ; i <= ns; ++ i)
scanf("%s", str[i] + );
for(int i = ; i <= ns; ++ i){
for(int j = ; j <= ms; ++ j){
if(str[i][j] == 'm') ++ tp1;
else if (str[i][j] == 'H') ++ tp2;
}
}
Net.n = tp1 + tp2;
for(int i = ; i <= ns; ++ i){
for(int j = ; j <= ms; ++ j){
if(str[i][j] == 'm'){
++ cnt1;
Net.Add(, cnt1, , , );
mm[cnt1] = (Position){i, j, cnt1};
}
}
}
for(int i = ; i <= ns; ++ i){
for(int j = ; j <= ms; ++ j){
if(str[i][j] == 'H'){
++ cnt2;
Net.Add(tp1 + cnt2, Net.n + , , , );
HH[cnt2] = (Position){i, j, tp1 + cnt2};
}
}
}
Solve();
printf("%d\n", Net.MinCostMaxFlow(, Net.n + ));
} return ;
}

POJ 2195/HDU 1533

POJ 2195 Going Home / HDU 1533(最小费用最大流模板)的更多相关文章

  1. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  2. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  3. hdu 1533(最小费用最大流)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  4. POJ 2195:Going Home(最小费用最大流)

    http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...

  5. HDU 1533 最小费用最大流(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...

  6. HDU3376 最小费用最大流 模板2

    Matrix Again Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)To ...

  7. 图论算法-最小费用最大流模板【EK;Dinic】

    图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...

  8. 洛谷P3381 最小费用最大流模板

    https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...

  9. 最大流 && 最小费用最大流模板

    模板从  这里   搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) ; const int INF = 0x3f3f3f3f; struct Edge { int from ...

  10. poj 2195 最小费用最大流模板

    /*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...

随机推荐

  1. java下的第一个redis

    Redis支持很多编程语言的客户端,有C.C#.C++.Clojure.Common Lisp.Erlang.Go.Lua.Objective-C.PHP.Ruby.Scala,甚至更时髦的Node. ...

  2. CODEVS 1062 路由选择

    1062 路由选择  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 在网络通信中,经常需要求最短路径.但完全用最短路径传 ...

  3. ESP8266固件修改可以控制多个IO方法

    之前在论坛上找到了一个通过ESP8266可以控制GPIO0的固件和app,但是自己做的家庭影音灯光系统是需要控制多个IO从而控制STM32.通过观看大明的视频,了解了GPIO的控制方法. 在固件的ap ...

  4. VC:CString用法整理(转载)

    1.CString::IsEmpty BOOL IsEmpty( ) const; 返回值:如果CString 对象的长度为0,则返回非零值:否则返回0. 说明:此成员函数用来测试一个CString ...

  5. 继刚接触play framework后,一些心得

    我是个小菜鸟,我这些体会跟心得纯属个人观点,仅供参考,勿喷,我想记录下学习的历程,不断成长 在play2.0的框架里面  用到的最多的语言就是scala,对于习惯了java语言的我们来说  看这些语言 ...

  6. DataTables获取表单输入框数据

    $(document).ready(function() { var table = $('#example').DataTable(); $('button').click(function() { ...

  7. table行转列

    table行转列 摘要 在使用ews调用exhange的收件箱的并在h5页面显示邮件详情的时候,因为返回的每封邮件的内容都是htmlbody,没有textbody.每封邮件又没什么规律,用正则表达式来 ...

  8. cf C. Magic Formulas

    http://codeforces.com/contest/424/problem/C #include <cstdio> #include <cstring> #includ ...

  9. Tomcat查看用户名密码

    在非安装版的tomcat中,可以在{解压路径}/conf/tomcat_users.xml 配置文件中找到,也可以自己添加新的用户

  10. LVM(2)逻辑卷的扩展、缩减、快照卷

    一.扩展逻辑卷:lvextend   扩展逻辑卷物理边界    -L [+]# /PATH/TO/LV2G, +3G5G