来自FallDream的博客,未经允许,请勿转载,谢谢。

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

第一问谁都会 就是个sbdp , y坐标相同的一起转移

然后第二问看出求的是最少的链覆盖所有边 所以用上有源汇带上下界最小流 就行啦

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define MN 50000
#define S 0
#define TT 50004
#define SS 50002
#define T 50003
#define INF 2000000000
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
using namespace std;
inline int read()
{int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}struct Point{int x,y,id;}a[MN+5],b[MN+5],c[MN+5],d[MN+5];
struct edge{int to,next,w;}e[5000005];
int pos1[MN+5],pos2[MN+5],pos3[MN+5],aa[MN+5],pos4[MN+5],n,f[MN+5],g[MN+5],h[MN+5],ans=0,F[MN+5];
int head[T+5],D[T+5],cnt=1,C[T+5],q[MN+5],top=0,in[MN+5],out[MN+5],lt[MN+5],rt[MN+5];
vector<pa> to[MN*2+5];int mark[MN*2+5];
bool cmp1(Point a,Point b){return a.y==b.y?a.x<b.x:a.y<b.y;}
bool cmp2(Point a,Point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
bool cmp3(Point a,Point b){return (a.x-a.y==b.x-b.y)?a.y<b.y:(a.x-a.y<b.x-b.y);}
bool cmp4(Point a,Point b){return (a.x+a.y==b.x+b.y)?a.y<b.y:(a.x+a.y<b.x+b.y);}
inline void R(int&a,int b){if(b>a)a=b;}
inline void ins(int f,int t,int w)
{    e[++cnt]=(edge){t,head[f],w};head[f]=cnt;e[++cnt]=(edge){f,head[t],0};head[t]=cnt;++out[f];++in[t];
}
void Solve(int i)
{if(pos2[a[i].id]>1&&b[pos2[a[i].id]-1].x==a[i].x)R(f[a[i].id],f[b[pos2[a[i].id]-1].id]+1);if(pos3[a[i].id]>1&&c[pos3[a[i].id]-1].x-c[pos3[a[i].id]-1].y==a[i].x-a[i].y)R(f[a[i].id],f[c[pos3[a[i].id]-1].id]+1);if(pos4[a[i].id]>1&&d[pos4[a[i].id]-1].x+d[pos4[a[i].id]-1].y==a[i].x+a[i].y)R(f[a[i].id],f[d[pos4[a[i].id]-1].id]+1);
}void Work(int i,int id,int tot)
{if(pos2[a[i].id]>1&&b[pos2[a[i].id]-1].x==a[i].x&&f[b[pos2[a[i].id]-1].id]==tot-1)to[id].push_back(mp(b[pos2[a[i].id]-1].id,1));if(pos3[a[i].id]>1&&c[pos3[a[i].id]-1].x-c[pos3[a[i].id]-1].y==a[i].x-a[i].y&&f[c[pos3[a[i].id]-1].id]==tot-1)to[id].push_back(mp(c[pos3[a[i].id]-1].id,1));if(pos4[a[i].id]>1&&d[pos4[a[i].id]-1].x+d[pos4[a[i].id]-1].y==a[i].x+a[i].y&&f[d[pos4[a[i].id]-1].id]==tot-1)to[id].push_back(mp(d[pos4[a[i].id]-1].id,1));
}void Dfs(int I,int K,bool flag)
{if(I==n)return;int H=I+(K>1)*n;if(mark[H])return;mark[H]=1;to[H].clear();if(f[I]!=F[I]||(!mark[I]&&K==2)||(!mark[I+n]&&K==1)){Work(pos1[I],H,K&1?f[I]:F[I]);for(int ii=0;ii<to[H].size();++ii) {    ins(to[H][ii].first,I,INF),Dfs(to[H][ii].first,to[H][ii].second,flag); if(flag) printf("%d ",I),flag=0;}}to[H].clear();int i=pos1[I],j,k;if(K&1){for(j=i;j&&a[j].y==a[i].y;--j);++j;    for(k=i;k<=n&&a[k].y==a[i].y;++k);--k;for(int l=j;l<i;++l) if(f[I]==F[a[l].id]+i-j) to[H].push_back(mp(a[l].id,2));for(int ii=0;ii<to[H].size();++ii){Dfs(to[H][ii].first,to[H][ii].second,flag);if(flag){    for(int l=pos1[to[H][ii].first]-1;l>=j;--l) printf("%d ",a[l].id);for(int l=pos1[to[H][ii].first]+1;l<=i;++l) printf("%d ",a[l].id);flag=0;    }}to[H].clear();for(int l=k;l>i;--l)if(f[I]==F[a[l].id]+k-i)to[H].push_back(mp(a[l].id,2));for(int ii=0;ii<to[H].size();++ii) {Dfs(to[H][ii].first,to[H][ii].second,flag);if(flag){for(int l=pos1[to[H][ii].first]+1;l<=k;++l) printf("%d ",a[l].id); for(int l=pos1[to[H][ii].first]-1;l>=i;--l) printf("%d ",a[l].id);flag=0;}} }to[H].clear();
}int dfs(int x,int f)
{if(x==TT) return f;int used=0;for(int&i=C[x];i;i=e[i].next)if(e[i].w&&D[e[i].to]==D[x]+1){int w=dfs(e[i].to,min(e[i].w,f-used));used+=w;e[i].w-=w;e[i^1].w+=w;if(f==used) return f; }    return D[x]=-1,used;
}bool bfs()
{memset(D,0,sizeof(D));int i,j;for(D[q[top=i=1]=SS]=1;i<=top;++i)for(j=C[q[i]]=head[q[i]];j;j=e[j].next)if(e[j].w&&!D[e[j].to]) D[q[++top]=e[j].to]=D[q[i]]+1;return D[TT];
}int main()
{n=read();memset(f,128,sizeof(f));f[n+1]=0;for(int i=1;i<=n;++i) a[i].x=b[i].x=c[i].x=d[i].x=read(),a[i].y=b[i].y=c[i].y=d[i].y=read(),a[i].id=b[i].id=c[i].id=d[i].id=i;++n;a[n].id=b[n].id=c[n].id=d[n].id=n;sort(a+1,a+n+1,cmp1);sort(b+1,b+n+1,cmp2); sort(c+1,c+n+1,cmp3);sort(d+1,d+n+1,cmp4);for(int i=1;i<=n;++i) pos1[a[i].id]=pos2[b[i].id]=pos3[c[i].id]=pos4[d[i].id]=i;    for(int i=1,j;i<=n;i=j+1){for(j=i;j<=n&&a[j].y==a[i].y;++j)Solve(j),F[a[j].id]=f[a[j].id];--j;g[i-1]=h[j+1]=-INF;for(int k=i;k<=j;++k) g[k]=max(g[k-1],f[a[k].id]); for(int k=j;k>=i;--k) h[k]=max(h[k+1],f[a[k].id]);for(int k=i;k<=j;++k) R(f[a[k].id],max(g[k-1]+k-i,h[k+1]+j-k));for(int k=i;k<=j;++k) R(ans,f[a[k].id]);}printf("%d\n",ans);bool Flag=1;for(int i=1;i<=n;++i) if(f[i]==ans) Dfs(i,1,Flag),Flag=false;puts("");ans=0;for(int i=1;i<=n;++i) if(in[i]<out[i]) ins(i,TT,out[i]-in[i]);else if(out[i]<in[i]) ins(SS,i,in[i]-out[i]);    for(int i=1;i<=n;++i) ins(S,i,INF),ins(i,T,INF);while(bfs()) ans+=dfs(SS,INF);ins(T,S,INF);while(bfs()) ans+=dfs(SS,INF);printf("%d\n",e[cnt].w);return 0;
}

转载于:https://www.cnblogs.com/FallDream/p/Noi2015d2t3.html

[Noi2015]小园丁和老司机相关推荐

  1. P2304 [NOI2015] 小园丁与老司机(网络流/上下界网络流)

    P2304 [NOI2015] 小园丁与老司机 平面上有n个点,每次可以向左.右.上.左上45度.右上45度移动,然后直线移动到达第一个没有到过的点,如果没有这样的点就不能移动,求解一条最长路,然后求 ...

  2. BZOJ4200 洛谷2304 UOJ132:[NOI2015]小园丁与老司机——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4200 https://www.luogu.org/problemnew/show/P2304 ht ...

  3. 提高千倍效率的35个编码小技巧,老司机带你飞!

    点击关注公众号,实用技术文章及时了解 来源:henleylee.github.io/posts/2019/a780fcc1.html 前言 代码优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的 ...

  4. mysql入门到跑路_Mysql入门二十小题(DBA老司机带你删库到跑路)2018.11.26

    1. 请介绍数据库管理系统的种类及代表产品 RDBMS: mysql oracle mssql NoSQL: redis  mongoab  memcache 2. 请简述数据库管理系统的作用 数据存 ...

  5. oracle从删库到跑路,Mysql入门二十小题(DBA老司机带你删库到跑路)2018.11.26

    1. 请介绍数据库管理系统的种类及代表产品 RDBMS: mysql oracle mssql NoSQL: redis  mongoab  memcache 2. 请简述数据库管理系统的作用 数据存 ...

  6. 年薪30W的软件测试“老司机”工作经验

    这几天,新入职的小MM提议"老司机"们把自己这些年的软件测试工作经验跟大家分享一下,让新同学学习学习,利用空闲时间我整理了一些,可能不全,勉强看看,这也算是对自己这些年的工作总结. ...

  7. 【新梦想学员干货】必看!年薪30W的软件测试“老司机”工作经验。

    这几天,新入职的小MM提议"老司机"们把自己这些年的软件测试工作经验跟大家分享一下,让新同学学习学习,利用空闲时间我整理了一些,可能不全,勉强看看,这也算是对自己这些年的工作总结. ...

  8. 名悦集团:开车从不追尾,老司机分享驾驶避免事故小知识

    听交通广播,我们几乎每天都能听到高速路上,高架桥上,上班路上发生追尾事故,有时候是个平常的上下班高峰期.很多人会纳闷,车开的好好的,怎么就会发生追尾事故呢.开车在路上,难免会有磕磕碰碰.道路千万条,安 ...

  9. 老司机都在用的浏览器,体积小功能齐全,直呼内行

    现在市面上的浏览器简直是多不胜数,虽然数量多,但是好用的并不多.尤其是某些大厂的浏览器,无用的功能越来越多,越来越臃肿,体积也越来越大,使用体验还不好,有时候甚至不如一些小众浏览器.今天给大家安利2款 ...

  10. 视频教程-老司机讲前端之微信小程序开发成语消消乐游戏视频课程-微信开发

    老司机讲前端之微信小程序开发成语消消乐游戏视频课程 中国实战派HTML5培训第一人,微软技术讲师,曾任百合网技术总监,博看文思HTML5总监.陶国荣长期致力于HTML5.JavaScript.CSS3 ...

最新文章

  1. 企业生产环境下不同业务的linux分区建议
  2. 互联网协议 — TCP — 重传机制(可靠传输保障)
  3. C# 如何获取屏幕分辨率缩放比例
  4. Redis分布式锁抽丝剥茧
  5. ios 点击出现另外一套tabbar_IOS 点击tabbaritem跳转到一个新界面,且隐藏tabbar
  6. Android的APP多版本,Android多版本共存-基于gradle实现debug版和release版app共存
  7. MicroK8s及KubeFlow安装文档
  8. 全方位打造最强终端(iterm2 + oh my zsh)
  9. Linux下安装informix11.5数据库
  10. python基础6-控制语句
  11. 数据挖掘论文matlab,数据挖掘论文3000字范文参考
  12. 数据结构 实验2——表达式求值
  13. matlab 隐函数全微分,求隐函数的全微分
  14. cesium加载entity图片缩放_Linux 下最棒的 11 个图片查看器 | Linux 中国
  15. 51单片机——ADC模数转换、DAC数模转换PWM C语言入门编程
  16. 狂欢 724,致敬运维侠
  17. Convert() 转换时 报错:输入字符串的格式不正确
  18. ZZULIOJ:1088: 手机短号 (多实例)
  19. 机器学习(四):CART分类树(基础篇)
  20. python模块之StringIO

热门文章

  1. Ubuntu安装NVDIA显卡驱动,CUDA及cuDNN
  2. 古剑奇谭3steam服务器稳定吗,国产游戏《古剑奇谭3》占据steam热销榜第一?这么好玩吗?...
  3. 使用ROS提取udacity .bag文件中的压缩图片
  4. 抢Google等巨头生意,纽约大学小伙挖掘并出售自己数据
  5. 大淘客cms源码修改二次开发实现淘京拼三合一功能
  6. 弱水三千,只取一瓢饮
  7. 【数学】连续,一致连续,Hölder连续,Lipschitz连续
  8. MVX-Net | 多模型三位像素网络用于3D目标检测
  9. 新零售O2O商城系统要怎么开发,这些功能都要有
  10. 台式计算机性能与种类,最新台式机处理器性能排行榜