题目

https://codeforces.com/gym/103427/problem/D

大意:给一个 a*b 的地图,有 n 个人和 n 个出口。出口只能用一次,人到了出口可以选择不出去。每次人可以LRUDS(不动)P(在出口或已经出去了才有这个,代表出去)五种操作(都是瞬移)。每个时刻每个位置只能有一个人。问 n 个人全出去的最少时间以及给出一种方案。

思路

这是官方题解 https://www.zhihu.com/question/500358591/answer/2239217951
注意数据都是100级别的。
首先,肯定有解,且不大于 a*b。因为可以把地图按贪吃蛇那样展开成一条线,然后一次分配出口即可。
那么,就可以先二分答案 t,再建造一个 t 层的图跑网络流。

如图,是个 t=3 的情形
每层有两组,上面那组每对点代表一个格子,下面那组每对点代表一个出口。之所以每层的点要成对出现,是为了各自在他们之间连上一条边权1的边来限制住流量。
跑完网络流,每条流量代表一个人的路径。最终流量刚好为 n 则代表可以成功。
时间复杂度是二分乘上网络流。

代码

// https://codeforces.com/gym/103427/problem/D
#include <bits/stdc++.h>
using namespace std;template <typename Cap = int64_t>
class Dinic{private:struct E{int to, rev;Cap cap;char ch;};int n, st, ed;vector<vector<E>> G;vector<int> lv, idx;vector<pair<int, int>> egs;bool BFS(){lv.assign(n, -1);queue<int> bfs;bfs.push(st); lv[st] = 0;while (not bfs.empty()){int u = bfs.front(); bfs.pop();for (auto e: G[u]) {if (e.cap <= 0 or lv[e.to]!=-1) continue;bfs.push(e.to); lv[e.to] = lv[u] + 1;}}return lv[ed] != -1;}Cap DFS(int u, Cap f){if (u == ed) return f;Cap ret = 0;for(int &i = idx[u]; i < int(G[u].size()); ++i) {auto &e = G[u][i];if (e.cap <= 0 or lv[e.to]!=lv[u]+1) continue;Cap nf = DFS(e.to, min(f, e.cap));ret += nf; e.cap -= nf; f -= nf;G[e.to][e.rev].cap += nf;if (f == 0) return ret;}if (ret == 0) lv[u] = -1;return ret;}
public:void init(int n_) { G.assign(n = n_, vector<E>()); egs.clear(); }void addEdge(int u, int v, Cap c, char ch){G[u].push_back({v, int(G[v].size()), c, ch});G[v].push_back({u, int(G[u].size())-1, 0, ch});egs.emplace_back(v, int(G[v].size()) - 1);}Cap maxFlow(int st_, int ed_){st = st_, ed = ed_; Cap ret = 0;while (BFS()) {idx.assign(n, 0);Cap f = DFS(st, numeric_limits<Cap>::max());ret += f;if (f == 0) break;}return ret;}Cap flow_at(int eid) const {return G[egs[eid].first][egs[eid].second].cap;}// 输出答案void printAns(int Ha, int AB, int b, int t){for (int i=0; i<int(G[st].size()); i++) {int cur=G[st][i].to;int lst=ed;int x,y,xx,yy;x=xx=(cur-1)%Ha/2/b;y=yy=(cur-1)%Ha/2%b+1;string str;while (cur!=ed) {for (int j=0; j<int(G[cur].size()); j++) {E &e=G[cur][j];if (!e.cap && e.to!=lst && (e.to-1)/Ha>=(cur-1)/Ha) {if (e.ch>='A' && e.ch<='Z') str+=e.ch;//printf("%c",Ech[h]);lst=cur;cur=e.to;if (cur%Ha<=AB && (cur%2==0) && cur!=ed) {xx=(cur-1)%Ha/2/b;yy=(cur-1)%Ha/2%b+1;}break;}}}str.pop_back();printf("%d %d %d %d %s\n",x,y,xx,yy,str.c_str());}}
};int n,a,b;
int S,T;
int SUM,AB;
int sx[200],sy[200],ex[200],ey[200];
int fx[4][2]={{-1,0}, {1,0}, {0,-1}, {0,1}};
char ch[4]={'U','D','L','R'};
Dinic<int> DDD;
int trans_s2m(int x, int y, int t) {return (x*b+y)*2+SUM*t;}
int trans_e2m(int x, int t) {return x*2+AB+SUM*t;}bool check(int ttt)
{S=0;T=(ttt+1)*SUM;DDD.init(T+10);for (int i=1; i<=n; i++) {DDD.addEdge(S, trans_s2m(sx[i], sy[i], 0), 1, '.');}for (int t=0; t<ttt; t++) {for (int i=1; i<=a; i++)for (int j=1; j<=b; j++) {DDD.addEdge(trans_s2m(i,j,t), trans_s2m(i,j,t)+1, 1, '-');DDD.addEdge(trans_s2m(i,j,t)+1, trans_s2m(i,j,t+1), 1, 'S');for (int ff=0,ii,jj; ff<4; ff++) {ii=i+fx[ff][0], jj=j+fx[ff][1];if (ii<=0 || ii>a || jj<=0 || jj>b) continue;DDD.addEdge(trans_s2m(i,j,t)+1, trans_s2m(ii,jj,t+1), 1, ch[ff]);}for (int k=1; k<=n; k++) {DDD.addEdge(trans_e2m(k,t), trans_e2m(k,t)+1, 1, '-');DDD.addEdge(trans_e2m(k,t)+1, trans_e2m(k,t+1), 1, 'P');DDD.addEdge(trans_s2m(ex[k],ey[k],t)+1, trans_e2m(k,t+1), 1, 'P');}}}for (int i=1; i<=n; i++) {DDD.addEdge(trans_e2m(i,ttt), T, 1, '!');}int mxflow = DDD.maxFlow(S, T);return mxflow==n;
}void solve()
{scanf("%d%d%d",&n,&a,&b);AB=(a+1)*b*2;SUM=AB+n*2+2;vector<int> s(n+1);for (int i=1; i<=n; i++) {scanf("%d%d",&sx[i],&sy[i]);}for (int i=1; i<=n; i++) {scanf("%d%d", &ex[i], &ey[i]);}int ans=a*b;int L=0, R=a*b;while (L<=R) {int M=(L+R)>>1;if (check(M)) {ans=M;R=M-1;}else {L=M+1;}}check(ans);printf("%d\n",ans-1);DDD.printAns(SUM, AB, b, ans-1);}int main()
{solve();return 0;
}/*
// 3 4 4 1 1 1 4 4 4 1 3 2 3 2 4
// 3 2 2 1 1 1 2 2 2 1 1 2 1 2 2
// 2 3 3 1 1 1 3 1 2 2 210 1 100 1 17 1 49 1 12 1 37 1 83 1 44 1 75 1 78 1 72 1 3 1 75 1 47 1 55 1 81 1 6 1 59 1 17 1 68 1 28 1 24 10 1 100
1 17
1 49
1 12
1 37
1 83
1 44
1 75
1 78
1 72
1 3
1 75
1 47
1 55
1 81
1 6
1 59
1 17
1 68
1 28
1 24*/

D. Cross the Maze (网络流)相关推荐

  1. 强化学习q学习求最值_Q学习简介:强化学习

    强化学习q学习求最值 by ADL 通过ADL Q学习简介:强化学习 (An introduction to Q-Learning: reinforcement learning) This arti ...

  2. 【POJ - 2226】Muddy Fields(匈牙利算法 或 网络流dinic,二分图匹配,最小点覆盖,矩阵中优秀的建图方式 )

    题干: Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 5 ...

  3. 网络流专题(完结撒花)

    题目及链接地址 TOJ4085: Drainage Ditcheshttp://210.32.82.1/acmhome/showstatus.do?&page=1&problemId= ...

  4. 网络流题集【夏天的风】

    [HDU] 1532Drainage Ditches(基础)    [最大流] 3549 Flow Problem(基础)    [最大流] 3572 Task Schedule    [最大流]任务 ...

  5. Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法

    当使用jQuery Ajax post请求时可能会遇到类似这样的错误提示 XMLHttpRequest cannot load http://xxxxxx. Origin http://xxxxxx ...

  6. python损失函数实现_pytorch 实现cross entropy损失函数计算方式

    均方损失函数: 这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标. 很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数.因为一般损失函 ...

  7. 网络流24题(1) P2756 飞行员配对方案问题

    题目链接 题意:求一个最大的二分匹配,网络流最大流,自己造一个源点一个汇点,源点0到1~m流为1,m+1~n到汇点n+1流为1,然后就是题目给出的也是流为1,图就是这样的,套dinic一个板子,但是题 ...

  8. SuperMap iDesktop Cross 8C 开源桌面GIS下载与扩展开发

    2019独角兽企业重金招聘Python工程师标准>>> SuperMap iDesktop Cross 8C 扩展开发的环境配置

 工程源码:http://git.oschina. ...

  9. 平均符号熵的计算公式_交叉熵(Cross Entropy)从原理到代码解读

    交叉熵(Cross Entropy)是Shannon(香浓)信息论中的一个概念,在深度学习领域中解决分类问题时常用它作为损失函数. 原理部分:要想搞懂交叉熵需要先清楚一些概念,顺序如下:==1.自信息 ...

最新文章

  1. 提供《华容道与数据结构》代码供测试
  2. oracle 修索引改空间_记一次Oracle分区表全局索引重修的历程
  3. Android JUnit测试说明和实例演示
  4. vo listVO paggerHelper mapper使用原则
  5. Java面试知识点:File、IO流
  6. staruml透明_第05组 团队项目-需求分析报告
  7. Linux设备驱动开发详解-Note(5)---Linux 内核及内核编程(1)
  8. MySQL教程(十一)—— 操作数据表中的记录
  9. 官网MySQL下载速度慢的解决方法(5分钟内搞定)
  10. 解决远程桌面无法复制黏贴
  11. Apple移动设备处理器指令集 armv6、armv7、armv7s及arm64
  12. Java小白学习指南【day43】---Linux
  13. java saxreader 生成xml_SAXReader解析xml文件demo
  14. 如何下载无水印的抖音视频?
  15. C语言怎么用键盘复制,怎样复制粘贴,复制粘贴的快捷键.docx
  16. react 父组件数据更新 触发 子组件重新渲染
  17. linux下phylip软件构建NJ树,MEGA软件——系统发育树构建方法(图文讲解)
  18. 什么是CDN及CDN加速原理
  19. Oracle sql语句 待新增(新增字段)
  20. 测试网络连接速度 http://www.phoenixtv.com.cn/home/fhkp/testspeed.htm

热门文章

  1. linux外网sql server,在linux下连接MS SQL Server
  2. jeeplus框架使用技巧
  3. 游戏王计算机兽,游戏王电脑堺卡o组,自己组的来分享给大家一下构筑思路
  4. java单点登录跨域_深入浅出让你理解跨域与SSO单点登录原理与技术
  5. Netbeans8.1 IDE开发工具
  6. linux下FTP服务启动与关闭命令(转)
  7. 神人乔布斯辞职 几家欢乐几家愁?
  8. 如何向linux中添加头文件,linux添加头文件路径
  9. 浅入了解Vue开发小程序的技术原理
  10. 第一节 gRPC概述