题目大意:

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

算法讨论:

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

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

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

告诉一下。感谢万分。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7
  8 using namespace std;
  9
 10 struct MCMF{
 11     static const int N = 200 * 200 + 5;
 12     static const int M = 200 * 200 * 4 + 100;
 13     static const int oo = 0x3f3f3f3f;
 14
 15     int n, m, s, t, tot;
 16     int first[N], next[M];
 17     int u[M], v[M], cap[M], flow[M], cost[M];
 18     int dis[N], a[N], inque[N], pre[N];
 19
 20     void Clear(){memset(first, -1, sizeof first);tot = 0;}
 21
 22     void Add(int from, int to, int cp, int flw, int ct){
 23         u[tot] = from; v[tot] = to; cap[tot] = cp; flow[tot] = 0; cost[tot] = ct;
 24         next[tot] = first[u[tot]];
 25         first[u[tot]] = tot; ++ tot;
 26         u[tot] = to; v[tot] = from; cap[tot] = 0; flow[tot] = 0; cost[tot] = -ct;
 27         next[tot] = first[u[tot]];
 28         first[u[tot]] = tot; ++ tot;
 29     }
 30
 31     bool bfs(int &flw, int &ct){
 32         for(int i = 0; i <= n + 1; ++ i) dis[i] = oo;
 33         memset(inque, 0, sizeof inque);
 34         dis[s] = 0; pre[s] = 0; a[s] = oo; inque[s] = 1;
 35
 36         queue <int> q;
 37         q.push(s);
 38         while(!q.empty()){
 39             int now = q.front(); q.pop();
 40             inque[now] = 0;
 41
 42             for(int i = first[now]; i != -1; i = next[i]){
 43                 if(cap[i] > flow[i] && dis[v[i]] > dis[now] + cost[i]){
 44                     dis[v[i]] = dis[now] + cost[i];
 45                     a[v[i]] = min(a[now], cap[i] - flow[i]);
 46                     pre[v[i]] = i;
 47                     if(!inque[v[i]]){
 48                         inque[v[i]] = 1; q.push(v[i]);
 49                     }
 50                 }
 51             }
 52         }
 53
 54         if(dis[t] == oo) return false;
 55         flw += a[t];
 56         ct += dis[t] * a[t];
 57
 58         int now = t;
 59         while(now != s){
 60             flow[pre[now]] += a[t];
 61             flow[pre[now]^1] -= a[t];
 62             now = u[pre[now]];
 63         }
 64         return true;
 65     }
 66
 67     int MinCostMaxFlow(int s, int t){
 68         this->s = s;this->t = t;
 69         int flw = 0, ct = 0;
 70         while(bfs(flw, ct));
 71         return ct;
 72     }
 73 }Net;
 74
 75 struct Position{
 76     int l, r, id;
 77     Position(int _l=0, int _r=0, int _id=0): l(_l), r(_r), id(_id){}
 78 }mm[205], HH[205];
 79
 80 int ns, ms, cnt1, cnt2, tp1, tp2;
 81 char str[105][105];
 82
 83 void Solve(){
 84         for(int i = 1; i <= tp1; ++ i){
 85             for(int j = 1; j <= tp2; ++ j){
 86                 int x1 = mm[i].l, y1 = mm[i].r;
 87                 int x2 = HH[j].l, y2 = HH[j].r;
 88                 Net.Add(mm[i].id, HH[j].id, 1, 0, abs(x1-x2) + abs(y1-y2));
 89             }
 90         }
 91 }
 92
 93 int main(){
 94
 95     while(scanf("%d%d", &ns, &ms) && ns && ms){
 96         Net.Clear();
 97         cnt1 = cnt2 = 0;
 98         tp1 = tp2 = 0;
 99         for(int i = 1; i <= ns; ++ i)
100             scanf("%s", str[i] + 1);
101         for(int i = 1; i <= ns; ++ i){
102             for(int j = 1; j <= ms; ++ j){
103                 if(str[i][j] == 'm') ++ tp1;
104                 else if (str[i][j] == 'H') ++ tp2;
105             }
106         }
107         Net.n = tp1 + tp2;
108         for(int i = 1; i <= ns; ++ i){
109             for(int j = 1; j <= ms; ++ j){
110                 if(str[i][j] == 'm'){
111                     ++ cnt1;
112                     Net.Add(0, cnt1, 1, 0, 0);
113                     mm[cnt1] = (Position){i, j, cnt1};
114                 }
115             }
116         }
117         for(int i = 1; i <= ns; ++ i){
118             for(int j = 1; j <= ms; ++ j){
119                 if(str[i][j] == 'H'){
120                     ++ cnt2;
121                     Net.Add(tp1 + cnt2, Net.n + 1, 1, 0, 0);
122                     HH[cnt2] = (Position){i, j, tp1 + cnt2};
123                 }
124             }
125         }
126         Solve();
127         printf("%d\n", Net.MinCostMaxFlow(0, Net.n + 1));
128     }
129
130     return 0;
131 }

POJ 2195/HDU 1533

转载于:https://www.cnblogs.com/sxprovence/p/5106711.html

POJ 2195 Going Home / HDU 1533(最小费用最大流模板)相关推荐

  1. 费用流:最大费用最大流和最小费用最大流(模板)

    主要是思维建边,建有向边,然后跑模板就行了 可以解决KM算法所能解决的问题(完全取代) 可以解决非完备匹配问题中的最大权匹配和最小权匹配,分别对应着最大费用最大流和最小费用最大流 模板: 最大费用最大 ...

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

    模板从  这里   搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) const int maxn = 1e6 + 10; const int INF = 0x3f3f3f3 ...

  3. poj 3422 Kaka's Matrix Travels(最小费用最大流)

    题目链接 Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9394   Accep ...

  4. 乌鲁木齐网络赛J题(最小费用最大流模板)

    ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报  分类: 网络流(33)  版权声 ...

  5. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的 ...

  6. 【最小费用可行流模板】

    可能再也用不到了吧,今天整理电脑文件看到的,作为图论选手,留个纪念, //原图: 对于pi,拆点xi,yi s->S,[m,m],0 S->xi,[0,inf],0 yi->t,[0 ...

  7. HDU 4411Arrest(最小费用最大流)

    题意: 思路: [费用流]建图:代后 枚举k,求最小费用. 1 #include<stdio.h> 2 #include<string.h> 3 4 #include < ...

  8. hdu 6118 最小费用可行流(注意与最大流的区别)

    题意: 思路:....注意是可行流,在找增广路的时候条件要进行修改....修改的地方看代码注释 代码: #include<bits/stdc++.h> using namespace st ...

  9. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】最小费用最大流

    HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]带权二分图匹配 KM算法 In the kingdom of Henryy, there are N (2 <= N & ...

最新文章

  1. delphi批量存入多媒体字段 遇到内存溢出的坑
  2. 24小时临时邮箱_免费临时邮箱和接码平台
  3. linux里ip地址正常但远程连接不上,linux系统上解决postgres远程连接不上的问题
  4. java 综合练习_Java第二季6-1综合练习作业
  5. 无线通信中多径传播包络服从瑞利衰落衰落MATLAB仿真
  6. 一个学习代码的好网站
  7. python使用微信进行消息推送
  8. Java实现微信扫码关注公众号登录网站
  9. php 固定表头,PHPExcel如何冻结(锁定)表头
  10. 如何使用CubeMx生成一个DFU工程
  11. 安装oracle客户端此先决条件,xp系统下oracle 11g客户端安装先决条件检查全部失败...
  12. 帝国塔防2 empire defence 2的攻略
  13. 响铃:互金信贷的明天,或是一场一站式金融服务的盛宴
  14. Python实现手机号码归属地查询功能
  15. Movement Disorders脑电格兰杰因果分析:运动皮质在帕金森病复发性震颤中的作用
  16. C++ 机房预约系统
  17. 基于FPGA的ASK/FSK调制
  18. 1000美元实现自动驾驶,他是侠客还是极客?
  19. 在iPhone里玩电路设计:3D版电子电路沙盒上线,支持Arduino,真实还原1000+组件...
  20. 语言的翻译叫什么_独家整理MTI翻译硕士复试必考的翻译理论、策略和技巧

热门文章

  1. Android入门之基本布局
  2. SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用
  3. redis在windows10上跑起来
  4. zepto中的tap穿透
  5. 泛型DAO与泛型Service
  6. 15、sql语句集,Linux 下PHP查询mysql
  7. 软件架构的数据流总结(三)
  8. Javascript 問題汇总(不定期更新)【一】
  9. Optimize a Flex application using deferred instantiations
  10. Java程序员大神给初学者的学习方法路线建议