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。

(自认码风不错)

#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF=1e9;
const int N=5e4+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct point{
int x,y,b1,b2,id;
}p[N];
int n,b[N],c[N],d[N],e[N],l1,l2,l3,l4;
int to[][N],lft[N],straight[N],rigt[N];
int f[N],g[N],flor[N],num[N];
vector<int>ty[N];
inline bool cmpx(point a,point b){
return a.x<b.x;
}
inline bool cmpy(point a,point b){
return a.y>b.y;
}
void LSH(){
sort(b+,b+l1+);sort(c+,c+l2+);
sort(d+,d+l3+);sort(e+,e+l4+);
l1=unique(b+,b+l1+)-b-,l2=unique(c+,c+l2+)-c-;
l3=unique(d+,d+l3+)-d-,l4=unique(e+,e+l4+)-e-;
for(int i=;i<=n;i++){
p[i].x=lower_bound(b+,b+l1+,p[i].x)-b;
p[i].y=lower_bound(c+,c+l2+,p[i].y)-c;
p[i].b1=lower_bound(d+,d+l3+,p[i].b1)-d;
p[i].b2=lower_bound(e+,e+l4+,p[i].b2)-e;
}
}
void init(){
LSH();
sort(p+,p+n+,cmpy);
for(int i=;i<=n;i++){
int id=p[i].id;
to[][id]=lft[p[i].b2];
to[][id]=straight[p[i].x];
to[][id]=rigt[p[i].b1];
lft[p[i].b2]=id;
straight[p[i].x]=id;
rigt[p[i].b1]=id;
}
sort(p+,p+n+,cmpx);
for(int i=;i<=n;i++){
ty[p[i].y].push_back(p[i].id);
flor[p[i].id]=p[i].y;
num[p[i].id]=ty[p[i].y].size()-;
}
}
int pre[N],lrs[N];
void output(int id){
if(id!=lrs[id]){
int fll=flor[id];
if(num[id]<num[lrs[id]]){
for(int i=num[id]-;i>=;i--)printf("%d ",ty[fll][i]);
for(int i=num[id]+;i<=num[lrs[id]];i++)printf("%d ",ty[fll][i]);
}else{
int sz=ty[fll].size();
for(int i=num[id]+;i<sz;i++)printf("%d ",ty[fll][i]);
for(int i=num[id]-;i>=num[lrs[id]];i--)printf("%d ",ty[fll][i]);
}
}
id=lrs[id];
if(pre[id]){
printf("%d ",pre[id]);
output(pre[id]);
}
}
void work1(){
init();
for(int i=l2;i>=;i--){
int maxn=,id=,sz=ty[i].size();
for(int j=;j<sz;j++){//处理直行和向右再左走
int I=ty[i][j];
int J1=to[][I],J2=to[][I],J3=to[][I];
if(J1&&g[I]<f[J1])g[I]=f[J1],pre[I]=J1;
if(J2&&g[I]<f[J2])g[I]=f[J2],pre[I]=J2;
if(J3&&g[I]<f[J3])g[I]=f[J3],pre[I]=J3;
if(maxn>g[I]+)f[I]=maxn,lrs[I]=id;
else f[I]=g[I]+,lrs[I]=I;
if(sz-j+g[I]>maxn)maxn=sz-j+g[I],id=I;
}
maxn=id=;
for(int j=sz-;j>=;j--){//处理向左再右走
int I=ty[i][j];
if(maxn>f[I])f[I]=maxn,lrs[I]=id;
if(g[I]+j+>maxn)maxn=g[I]+j+,id=I;
}
}
printf("%d\n",f[n]-);output(n);puts("");
}
struct node{
int to,nxt,w;
}edge[N*];
int cnt,head[N],S,T,du[N];
int cur[N],lev[N],dui[N];
bool ok[N];
inline void adde(int u,int v,int w){
edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;
edge[++cnt].to=u;edge[cnt].w=;edge[cnt].nxt=head[v];head[v]=cnt;
}
inline void add(int u,int v){
for(int i=head[u];i!=-;i=edge[i].nxt)
if(edge[i].to==v)return;
du[u]--;du[v]++;adde(u,v,INF-);
}
bool bfs(int m){
int r;
for(int i=;i<=m;i++){
cur[i]=head[i];lev[i]=-;
}
dui[r=]=S;lev[S]=;
for(int i=;i<=r;i++){
int u=dui[i];
for(int j=head[u];j!=-;j=edge[j].nxt){
int v=edge[j].to,w=edge[j].w;
if(lev[v]==-&&w){
lev[v]=lev[u]+;
dui[++r]=v;
if(v==T)return ;
}
}
}
return ;
}
int dinic(int u,int flow,int m){
if(u==m)return flow;
int res=,delta;
for(int &i=cur[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(lev[v]>lev[u]&&edge[i].w){
delta=dinic(v,min(flow,edge[i].w),m);
if(delta){
edge[i].w-=delta;
edge[i^].w+=delta;
res+=delta;
if(res==flow)break;
}
}
}
if(res!=flow)lev[u]=-;
return res;
}
void build(){
ok[n]=;
for(int i=;i<=l2;i++){
int sz=ty[i].size();
for(int j=;j<sz;j++){
int I=ty[i][j];
if(!ok[I])continue;
for(int k=;k<j;k++){
int J=ty[i][k];
int K1=to[][J],K2=to[][J],K3=to[][J];
if(K1&&f[K1]+sz-k==f[I])add(J,K1),ok[K1]=;
if(K2&&f[K2]+sz-k==f[I])add(J,K2),ok[K2]=;
if(K3&&f[K3]+sz-k==f[I])add(J,K3),ok[K3]=;
}
for(int k=j+;k<sz;k++){
int J=ty[i][k];
int K1=to[][J],K2=to[][J],K3=to[][J];
if(K1&&f[K1]+k+==f[I])add(J,K1),ok[K1]=;
if(K2&&f[K2]+k+==f[I])add(J,K2),ok[K2]=;
if(K3&&f[K3]+k+==f[I])add(J,K3),ok[K3]=;
}
int K1=to[][I],K2=to[][I],K3=to[][I];
if(K1&&f[K1]+==f[I])add(I,K1),ok[K1]=;
if(K2&&f[K2]+==f[I])add(I,K2),ok[K2]=;
if(K3&&f[K3]+==f[I])add(I,K3),ok[K3]=;
}
}
}
void work2(){
memset(head,-,sizeof(head));cnt=-;
build();
S=n+,T=S+;
int ans=;
for(int i=;i<=n;i++){
if(du[i]>)adde(S,i,du[i]),ans+=du[i];
else if(du[i]<)adde(i,T,-du[i]);
}
while(bfs(T))ans-=dinic(S,INF,T);
printf("%d\n",ans);
}
int main(){
n=read();
for(int i=;i<=n;i++){
p[i].x=b[++l1]=read();
p[i].y=c[++l2]=read();
p[i].b1=d[++l3]=p[i].y-p[i].x;
p[i].b2=e[++l4]=p[i].y+p[i].x;
p[i].id=i;
}
p[++n].x=b[++l1]=;
p[n].y=c[++l2]=;
p[n].b1=d[++l3]=;
p[n].b2=e[++l4]=;
p[n].id=n;
work1();work2();
return ;
}

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

+本文作者: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. IAR环境下编译CC2640入门开发

    1. 安装SDK包,之后导入AIR里面,编译报错 看样子似乎是xdc工具的路径配置不对,进入路径配置对话窗 开始配置 配置完之后,重新编译 Fatal Error[Pe1696]: cannot op ...

  2. 利尔达NB-IOT模块烧写固件的步骤

    1. NB-IOT是3个内核,用户开发的是A核,就是应用核,用Eclipse软件打开软件SDK之后,会生成一个bin文件(应用核的bin),现在就是要把bin文件合并到包里面(3个内核的bin),一起 ...

  3. 利尔达CC3200模块第一篇之-wlan_ap例程测试

    1. 本次采用利尔达的CC3200模块,CC3200主时钟80M,内部没有flash,必须外接SPI Flash.本次测试采用利尔达科技的CC3200的底板和模块(左边).烧写连接VCC, GND, ...

  4. Redis系列八 使用Jedis

    使用Jedis jar操作Redis 1.配置redis.conf文件,修改 2.建java工程,加入 jedis jar包 3.代码示例: package com.ntjr.redis; impor ...

  5. CRL2.1更新

    增加没有主键ID的抽象类,使能自义主键字段实现MODEL抽象类定义结构为 /// <summary> /// 基类,不包含任何字段 /// 如果有自定义主键名对象,请继承此类型 /// & ...

  6. 会声会影X10x9x8最新教程

    会声会影X10x9x8最新最全教程,全部都是干货,包含素材的,下载地址:百度网盘, https://pan.baidu.com/s/1AyVS-C_VcTEz_ir70u08xQ 以下为部分内容截图: ...

  7. 第一阶段·Linux运维基础-第2章·Linux系统目录结构介绍

    01 变量与PS1 02 添加用户 03 关闭SELinux 04 关闭iptables 05 显示中文乱码排查过程 06 总结 07 目录结构课程内容 08 Linux目录结构特点 09 Linux ...

  8. TW实习日记:第19天

    今天一早上改完信息门户的代码之后,发现接口又出了问题,查了半天都不知道,原来又是网端的问题...真是心累啊,调整了一些细节样式,以及终于把企业微信的消息推送功能做完了.关键就在于有个表存放微信id的字 ...

  9. 剑指offer-二叉树中和为某一值的路径24

    题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大 ...

  10. [ Continuously Update ] The Paper List of Image / Video Captioning

    Papers Published in 2018 Convolutional Image Captioning - Jyoti Aneja et al., CVPR 2018 - [ Paper Re ...