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. MySQL高级-MySQL安装

    1.mysql安装 检查系统是否安装过mysql 查询命令:rpm -qa|grep -i mysql 删除命令:rpm -e RPM软件包名(该名字是上一个命令查出来的名字) 安装命令:rpm -i ...

  2. linux下实现ssh无密码登录访问

    在192.168.9.51机器上 1)运行:#ssh-keygen -t rsa 2)然后拍两下回车(均选择默认) 3)运行: #ssh-copy-id -i /root/.ssh/id_rsa.pu ...

  3. C#中创建二维数组,使用[][]和[,]的区别

    C#中,我们在创建二维数组的时候,一般使用arr[][]的形式,例如 int[][] aInt = new int[2][]; 但声明二维数组还有一种方法,是使用arr[,]的形式.两者有什么区别呢? ...

  4. 在生产环境中部署asp.net core应用

    设备:阿里云ECS云主机 操作系统:centos 7 操作步骤: 1 安装.net core sdk: # 添加dotnet product feed sudo rpm --import https: ...

  5. linux 安装 node.js

    wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gztar zxvf node-v0.10.26.tar.gzcd node-v0.10. ...

  6. Linux命令应用大词典-第25章 备份与还原

    25.1 mkisofs:创建ISO9660/Joliet/hfs文件系统

  7. 哈希表 -数据结构(C语言实现)

    读数据结构与算法分析 哈希表 一种用于以常数平均时间执行插入.删除和查找操作的数据结构. 但是是无序的 一般想法 通常为一个包含关键字的具有固定大小的数组 每个关键字通过散列函数映射到数组中 冲突:两 ...

  8. python3爬虫-快速入门-爬取图片和标题

    直接上代码,先来个爬取豆瓣图片的,大致思路就是发送请求-得到响应数据-储存数据,原理的话可以先看看这个 https://www.cnblogs.com/sss4/p/7809821.html impo ...

  9. [HNOI2018]寻宝游戏(题解转载自别处)

    题解(自别处转载): Luogu CSDN 这题关键是将运算符也替换成0,1 然后在运算符与原串混杂里找规律. 而且替换的方式也有所要求,考场上两种替换方式都要尝试. #include <bit ...

  10. 四:ResourceManger Restart

    概述: RM是yarn中最重要的组件.但是只有一个RM,因此存在单点失败的问题.RM的重启有两种方式: 1.(Non-work-preserving RM restart) 不保留工作状态的重启   ...