https://www.lydsy.com/JudgeOnline/problem.php?id=4200

https://www.luogu.org/problemnew/show/P2304

http://uoj.ac/problem/132

小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面。田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2,3,…,n,每棵树可以看作平面上的一个点,其中第 ii 棵树 (1≤i≤n1≤i≤n) 位于坐标 (xi,yi)(xi,yi)。任意两棵树的坐标均不相同。
老司机 Mr. P 从原点 (0,0)(0,0) 驾车出发,进行若干轮行动。每一轮,Mr. P 首先选择任意一个满足以下条件的方向:
为左、右、上、左上 45∘45∘ 、右上 45∘45∘ 五个方向之一。
沿此方向前进可以到达一棵他尚未许愿过的树。
完成选择后,Mr. P 沿该方向直线前进,必须到达该方向上距离最近的尚未许愿的树,在树下许愿并继续下一轮行动。如果没有满足条件的方向可供选择,则停止行动。他会采取最优策略,在尽可能多的树下许愿。若最优策略不唯一,可以选择任意一种。
不幸的是,小园丁 Mr. S 发现由于田野土质松软,老司机 Mr. P 的小汽车在每轮行进过程中,都会在田野上留下一条车辙印,一条车辙印可看作以两棵树(或原点和一棵树)为端点的一条线段。
在 Mr. P 之后,还有很多许愿者计划驾车来田野许愿,这些许愿者都会像 Mr. P 一样任选一种最优策略行动。Mr. S 认为非左右方向(即上、左上 45∘45∘ 、右上 45∘45∘ 三个方向)的车辙印很不美观,为了维护田野的形象,他打算租用一些轧路机,在这群许愿者到来之前夯实所有“可能留下非左右方向车辙印”的地面。
“可能留下非左右方向车辙印”的地面应当是田野上的若干条线段,其中每条线段都包含在某一种最优策略的行进路线中。每台轧路机都采取满足以下三个条件的工作模式:
从原点或任意一棵树出发。
只能向上、左上 45∘45∘ 、右上 45∘45∘ 三个方向之一移动,并且只能在树下改变方向或停止。
只能经过“可能留下非左右方向车辙印”的地面,但是同一块地面可以被多台轧路机经过。
现在 Mr. P 和 Mr. S 分别向你提出了一个问题:
请给 Mr .P 指出任意一条最优路线。
请告诉 Mr. S 最少需要租用多少台轧路机。

哈哈哈我可能是疯了所以才去做了码农题,然后dp不会最小流写跪哈哈哈

直接看这个吧,心累到懒得讲题解了:https://blog.csdn.net/litble/article/details/80463466

另外开O2的时候普通的最小流也可以通过,不开的时候就会奇妙RE。

(自认码风不错)

  1. #include<cmath>
  2. #include<stack>
  3. #include<queue>
  4. #include<cstdio>
  5. #include<cctype>
  6. #include<vector>
  7. #include<cstdlib>
  8. #include<cstring>
  9. #include<iostream>
  10. #include<algorithm>
  11. using namespace std;
  12. typedef long long ll;
  13. const int INF=1e9;
  14. const int N=5e4+;
  15. inline int read(){
  16. int X=,w=;char ch=;
  17. while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
  18. while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
  19. return w?-X:X;
  20. }
  21. struct point{
  22. int x,y,b1,b2,id;
  23. }p[N];
  24. int n,b[N],c[N],d[N],e[N],l1,l2,l3,l4;
  25. int to[][N],lft[N],straight[N],rigt[N];
  26. int f[N],g[N],flor[N],num[N];
  27. vector<int>ty[N];
  28. inline bool cmpx(point a,point b){
  29. return a.x<b.x;
  30. }
  31. inline bool cmpy(point a,point b){
  32. return a.y>b.y;
  33. }
  34. void LSH(){
  35. sort(b+,b+l1+);sort(c+,c+l2+);
  36. sort(d+,d+l3+);sort(e+,e+l4+);
  37. l1=unique(b+,b+l1+)-b-,l2=unique(c+,c+l2+)-c-;
  38. l3=unique(d+,d+l3+)-d-,l4=unique(e+,e+l4+)-e-;
  39. for(int i=;i<=n;i++){
  40. p[i].x=lower_bound(b+,b+l1+,p[i].x)-b;
  41. p[i].y=lower_bound(c+,c+l2+,p[i].y)-c;
  42. p[i].b1=lower_bound(d+,d+l3+,p[i].b1)-d;
  43. p[i].b2=lower_bound(e+,e+l4+,p[i].b2)-e;
  44. }
  45. }
  46. void init(){
  47. LSH();
  48. sort(p+,p+n+,cmpy);
  49. for(int i=;i<=n;i++){
  50. int id=p[i].id;
  51. to[][id]=lft[p[i].b2];
  52. to[][id]=straight[p[i].x];
  53. to[][id]=rigt[p[i].b1];
  54. lft[p[i].b2]=id;
  55. straight[p[i].x]=id;
  56. rigt[p[i].b1]=id;
  57. }
  58. sort(p+,p+n+,cmpx);
  59. for(int i=;i<=n;i++){
  60. ty[p[i].y].push_back(p[i].id);
  61. flor[p[i].id]=p[i].y;
  62. num[p[i].id]=ty[p[i].y].size()-;
  63. }
  64. }
  65. int pre[N],lrs[N];
  66. void output(int id){
  67. if(id!=lrs[id]){
  68. int fll=flor[id];
  69. if(num[id]<num[lrs[id]]){
  70. for(int i=num[id]-;i>=;i--)printf("%d ",ty[fll][i]);
  71. for(int i=num[id]+;i<=num[lrs[id]];i++)printf("%d ",ty[fll][i]);
  72. }else{
  73. int sz=ty[fll].size();
  74. for(int i=num[id]+;i<sz;i++)printf("%d ",ty[fll][i]);
  75. for(int i=num[id]-;i>=num[lrs[id]];i--)printf("%d ",ty[fll][i]);
  76. }
  77. }
  78. id=lrs[id];
  79. if(pre[id]){
  80. printf("%d ",pre[id]);
  81. output(pre[id]);
  82. }
  83. }
  84. void work1(){
  85. init();
  86. for(int i=l2;i>=;i--){
  87. int maxn=,id=,sz=ty[i].size();
  88. for(int j=;j<sz;j++){//处理直行和向右再左走
  89. int I=ty[i][j];
  90. int J1=to[][I],J2=to[][I],J3=to[][I];
  91. if(J1&&g[I]<f[J1])g[I]=f[J1],pre[I]=J1;
  92. if(J2&&g[I]<f[J2])g[I]=f[J2],pre[I]=J2;
  93. if(J3&&g[I]<f[J3])g[I]=f[J3],pre[I]=J3;
  94. if(maxn>g[I]+)f[I]=maxn,lrs[I]=id;
  95. else f[I]=g[I]+,lrs[I]=I;
  96. if(sz-j+g[I]>maxn)maxn=sz-j+g[I],id=I;
  97. }
  98. maxn=id=;
  99. for(int j=sz-;j>=;j--){//处理向左再右走
  100. int I=ty[i][j];
  101. if(maxn>f[I])f[I]=maxn,lrs[I]=id;
  102. if(g[I]+j+>maxn)maxn=g[I]+j+,id=I;
  103. }
  104. }
  105. printf("%d\n",f[n]-);output(n);puts("");
  106. }
  107. struct node{
  108. int to,nxt,w;
  109. }edge[N*];
  110. int cnt,head[N],S,T,du[N];
  111. int cur[N],lev[N],dui[N];
  112. bool ok[N];
  113. inline void adde(int u,int v,int w){
  114. edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;
  115. edge[++cnt].to=u;edge[cnt].w=;edge[cnt].nxt=head[v];head[v]=cnt;
  116. }
  117. inline void add(int u,int v){
  118. for(int i=head[u];i!=-;i=edge[i].nxt)
  119. if(edge[i].to==v)return;
  120. du[u]--;du[v]++;adde(u,v,INF-);
  121. }
  122. bool bfs(int m){
  123. int r;
  124. for(int i=;i<=m;i++){
  125. cur[i]=head[i];lev[i]=-;
  126. }
  127. dui[r=]=S;lev[S]=;
  128. for(int i=;i<=r;i++){
  129. int u=dui[i];
  130. for(int j=head[u];j!=-;j=edge[j].nxt){
  131. int v=edge[j].to,w=edge[j].w;
  132. if(lev[v]==-&&w){
  133. lev[v]=lev[u]+;
  134. dui[++r]=v;
  135. if(v==T)return ;
  136. }
  137. }
  138. }
  139. return ;
  140. }
  141. int dinic(int u,int flow,int m){
  142. if(u==m)return flow;
  143. int res=,delta;
  144. for(int &i=cur[u];i!=-;i=edge[i].nxt){
  145. int v=edge[i].to;
  146. if(lev[v]>lev[u]&&edge[i].w){
  147. delta=dinic(v,min(flow,edge[i].w),m);
  148. if(delta){
  149. edge[i].w-=delta;
  150. edge[i^].w+=delta;
  151. res+=delta;
  152. if(res==flow)break;
  153. }
  154. }
  155. }
  156. if(res!=flow)lev[u]=-;
  157. return res;
  158. }
  159. void build(){
  160. ok[n]=;
  161. for(int i=;i<=l2;i++){
  162. int sz=ty[i].size();
  163. for(int j=;j<sz;j++){
  164. int I=ty[i][j];
  165. if(!ok[I])continue;
  166. for(int k=;k<j;k++){
  167. int J=ty[i][k];
  168. int K1=to[][J],K2=to[][J],K3=to[][J];
  169. if(K1&&f[K1]+sz-k==f[I])add(J,K1),ok[K1]=;
  170. if(K2&&f[K2]+sz-k==f[I])add(J,K2),ok[K2]=;
  171. if(K3&&f[K3]+sz-k==f[I])add(J,K3),ok[K3]=;
  172. }
  173. for(int k=j+;k<sz;k++){
  174. int J=ty[i][k];
  175. int K1=to[][J],K2=to[][J],K3=to[][J];
  176. if(K1&&f[K1]+k+==f[I])add(J,K1),ok[K1]=;
  177. if(K2&&f[K2]+k+==f[I])add(J,K2),ok[K2]=;
  178. if(K3&&f[K3]+k+==f[I])add(J,K3),ok[K3]=;
  179. }
  180. int K1=to[][I],K2=to[][I],K3=to[][I];
  181. if(K1&&f[K1]+==f[I])add(I,K1),ok[K1]=;
  182. if(K2&&f[K2]+==f[I])add(I,K2),ok[K2]=;
  183. if(K3&&f[K3]+==f[I])add(I,K3),ok[K3]=;
  184. }
  185. }
  186. }
  187. void work2(){
  188. memset(head,-,sizeof(head));cnt=-;
  189. build();
  190. S=n+,T=S+;
  191. int ans=;
  192. for(int i=;i<=n;i++){
  193. if(du[i]>)adde(S,i,du[i]),ans+=du[i];
  194. else if(du[i]<)adde(i,T,-du[i]);
  195. }
  196. while(bfs(T))ans-=dinic(S,INF,T);
  197. printf("%d\n",ans);
  198. }
  199. int main(){
  200. n=read();
  201. for(int i=;i<=n;i++){
  202. p[i].x=b[++l1]=read();
  203. p[i].y=c[++l2]=read();
  204. p[i].b1=d[++l3]=p[i].y-p[i].x;
  205. p[i].b2=e[++l4]=p[i].y+p[i].x;
  206. p[i].id=i;
  207. }
  208. p[++n].x=b[++l1]=;
  209. p[n].y=c[++l2]=;
  210. p[n].b1=d[++l3]=;
  211. p[n].b2=e[++l4]=;
  212. p[n].id=n;
  213. work1();work2();
  214. return ;
  215. }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4200 & 洛谷2304 & UOJ132:[NOI2015]小园丁与老司机——题解的更多相关文章

  1. 【洛谷2304_LOJ2134】[NOI2015]小园丁与老司机(动态规划_网络流)

    题目: 洛谷 2304 LOJ 2134 (LOJ 上每个测试点有部分分) 写了快一天 -- 好菜啊 分析: 毒瘤二合一题 -- 注意本题(及本文)使用 \(x\) 向右,\(y\) 向上的「数学坐标 ...

  2. [UOJ#132][BZOJ4200][luogu_P2304][NOI2015]小园丁与老司机

    [UOJ#132][BZOJ4200][luogu_P2304][NOI2015]小园丁与老司机 试题描述 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 \(n\) 棵许愿 ...

  3. [BZOJ4200][Noi2015]小园丁与老司机

    4200: [Noi2015]小园丁与老司机 Time Limit: 20 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 106  Solved ...

  4. 【BZOJ4200】[Noi2015]小园丁与老司机 DP+最小流

    [BZOJ2839][Noi2015]小园丁与老司机 Description 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2, ...

  5. luogu P2304 [NOI2015]小园丁与老司机 dp 上下界网络流

    LINK:小园丁与老司机 苦心人 天不负 卧薪尝胆 三千越甲可吞吴 AC的刹那 真的是泪目啊 很久以前就写了 当时记得特别清楚 写到肚子疼.. 调到胳膊疼.. ex到根不不想看的程度. 当时wa了 一 ...

  6. uoj132/BZOJ4200/洛谷P2304 [Noi2015]小园丁与老司机 【dp + 带上下界网络流】

    题目链接 uoj132 题解 真是一道大码题,,,肝了一个上午 老司机的部分是一个\(dp\),观察点是按\(y\)分层的,而且按每层点的上限来看可以使用\(O(nd)\)的\(dp\),其中\(d\ ...

  7. 【bzoj4200】[Noi2015]小园丁与老司机 STL-map+dp+有上下界最小流

    题目描述 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2,3,…,n,每棵树可以看作平面上的一个点,其中第 ii 棵树 (1≤ ...

  8. bzoj 4200: [Noi2015]小园丁与老司机【dp+有上下界最小流】

    洛谷上有个点死活卡不过去,不知道是哪里写丑了orz 参考:https://www.cnblogs.com/ditoly/p/BZOJ4200.html 从上往下dp,设f为不向左右走直接上去的值,g为 ...

  9. [BZOJ]4200: [Noi2015]小园丁与老司机

    Time Limit: 20 Sec  Memory Limit: 512 MBSec  Special Judge Description 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维 ...

随机推荐

  1. vs找不到lib以及编译的link过程中出现的问题

    1.#pragma comment 程序中已经通过该语句完成lib库的引入,如果再在input里面添加lib库就会报错: 2.要在general的“导入外部库”的设置选项的目录下面添加引用到的lib库 ...

  2. 「日常训练」Watering Flowers(Codeforces Round #340 Div.2 C)

    题意与分析 (CodeForces 617C) 题意是这样的:一个花圃中有若干花和两个喷泉,你可以调节水的压力使得两个喷泉各自分别以\(r_1\)和\(r_2\)为最远距离向外喷水.你需要调整\(r_ ...

  3. pycharm 3.4 亲测可使用到2019年2月的注册码,要用者从速

    注册码: D87IQPUU3Q-eyJsaWNlbnNlSWQiOiJEODdJUVBVVTNRIiwibGljZW5zZWVOYW1lIjoiTnNzIEltIiwiYXNzaWduZWVOYW1l ...

  4. 【转】Bootstrap FileInput中文API整理

    Bootstrap FileInput中文API整理 这段时间做项目用到bootstrap fileinput插件上传文件,在用的过程中,网上能查到的api都不是很全,所以想着整理一份比较详细的文档, ...

  5. lintcode373 奇偶分割数组

    奇偶分割数组 分割一个整数数组,使得奇数在前偶数在后. 您在真实的面试中是否遇到过这个题? Yes 样例 给定 [1, 2, 3, 4],返回 [1, 3, 2, 4]. 我的方法:设定两个数组,分别 ...

  6. block inline 和 inline-block

    概念 block和inline这两个概念是简略的说法,完整确切的说应该是 block-level elements (块级元素) 和 inline elements (内联元素). block元素通常 ...

  7. 将SqlDataReader 数据集转化为datatbale ,在将datatable 转化为iList

    public IList GetModelList(string tablename, string where) { IList list = null; DataTable dataTable = ...

  8. popen()与system()

    一.popen() 用途:执行shell命令(并读取其输出或向其发送一些输入) 特点:通过管道来与shell命令进行通信 二.system()

  9. PhotoShop基础工具 -- 移动工具

    还是学点美工的东西吧, 业余爱好   比学编程还难 PS版本 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左侧的是工具栏, 每选中一个工具, 在菜单 ...

  10. 团队选题报告(i know)

    一.团队成员及分工 团队名称:I know 团队成员: 陈家权:选题报告word撰写 赖晓连:ppt制作,原型设计 雷晶:ppt制作,原型设计 林巧娜:原型设计,博客随笔撰写 庄加鑫:选题报告word ...