洛谷上有个点死活卡不过去,不知道是哪里写丑了orz

参考:https://www.cnblogs.com/ditoly/p/BZOJ4200.html

从上往下dp,设f为不向左右走直接上去的值,g为先向左右走一步再上去,至于找每个方向上的点,分别按x,y,x+y,x-y排序然后二分即可

然后建出左上右上的图,跑有上下界最小流即可

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
const int N=50005;
int n,rl[N],t1[N],t2[N],t3[N],l[N],r[N],f[N],ff[N],lf[N],rf[N],a[N],an,d[N],u[N],c[N],s,t,ans,h[N],cnt=1,le[N];
vector<int>v,b[N];
struct qwe
{
int ne,to,va;
}e[N*10];
struct dian
{
int x,y,id;
}p[N];
bool cmp1(const dian&a,const dian&b)
{
return a.x+a.y==b.x+b.y?a.y<b.y:a.x+a.y<b.x+b.y;
}
bool cmp2(const dian&a,const dian&b)
{
return a.x-a.y==b.x-b.y?a.y<b.y:a.x-a.y<b.x-b.y;
}
bool cmp3(const dian&a,const dian&b)
{
return a.x==b.x?a.y<b.y:a.x<b.x;
}
bool cmp4(const dian&a,const dian&b)
{
return a.y==b.y?a.x<b.x:a.y<b.y;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void add(int u,int v,int w)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
e[cnt].va=w;
h[u]=cnt;
}
void ins(int u,int v,int w)
{
add(u,v,w);
add(v,u,0);
}
void wk(int u,int v,int l,int r)
{
c[u]-=l,c[v]+=l;
ins(u,v,r-l);
}
bool bfs()
{
memset(le,0,sizeof(le));
queue<int>q;
le[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=h[u];i;i=e[i].ne)
if(e[i].va>0&&!le[e[i].to])
{
le[e[i].to]=le[u]+1;
q.push(e[i].to);
}
}
return le[t];
}
int dfs(int u,int f)
{
if(u==t||!f)
return f;
int us=0;
for(int i=h[u];i&&us<f;i=e[i].ne)
if(e[i].va>0&&le[e[i].to]==le[u]+1)
{
int t=dfs(e[i].to,min(e[i].va,f-us));
e[i].va-=t;
e[i^1].va+=t;
us+=t;
}
if(!us)
le[u]=0;
return us;
}
int dinic()
{
int r=0;
while(bfs())
r+=dfs(s,1e9);
return r;
}
void jia(int x,int y)
{
if(ff[y]+1>f[x])
f[x]=ff[y]+1,b[x].clear();
if(ff[y]+1==f[x])
b[x].push_back(y);
}
void prin(int x)
{
a[++an]=x;
int u=1;
if(f[x]==ff[x])
{
u=0;
if(p[x].id)
prin(b[x][0]);
}
for(int i=l[x];u&&i<x;i++)
if(f[i]+x-l[x]==ff[x])
{
u=0;
for(int j=x;--j>i;)
a[++an]=j;
for(int j=l[x];j<=i;j++)
a[++an]=j;
if(p[i].id)
prin(b[i][0]);
}
for(int i=r[x];u&&i>x;i--)
if(f[i]+r[x]-x==ff[x])
{
u=0;
for(int j=x;++j<i;)
a[++an]=j;
for(int j=r[x];j>=i;j--)
a[++an]=j;
if(p[i].id)
prin(b[i][0]);
}
}
void dfs(int x)
{
if(d[x])
return;
d[x]=1;
if(f[x]==ff[x]&&!u[x])
{
u[x]=1;
for(int i=0;i<b[x].size();i++)
wk(b[x][i],x,1,1e9),dfs(b[x][i]);
}
for(int i=l[x];i<x;i++)
if(f[i]+x-l[x]==ff[x]&&!u[i])
{
u[i]=1;
for(int j=0;j<b[i].size();j++)
wk(b[i][j],i,1,1e9),dfs(b[i][j]);
}
for(int i=r[x];i>x;i--)
if(f[i]+r[x]-x==ff[x]&&!u[i])
{
u[i]=1;
for(int j=0;j<b[i].size();j++)
wk(b[i][j],i,1,1e9),dfs(b[i][j]);
}
}
int main()
{
n=read();
s=n+3,t=n+4;
for(int i=1;i<=n;++i)
p[i].x=read(),p[i].y=read(),p[i].id=i;
sort(p,p+n+1,cmp1);
for(int i=0;i<n;i++)
if(p[i].x+p[i].y==p[i+1].x+p[i+1].y)
t1[p[i].id]=p[i+1].id;
sort(p,p+n+1,cmp2);
for(int i=0;i<n;i++)
if(p[i].x-p[i].y==p[i+1].x-p[i+1].y)
t2[p[i].id]=p[i+1].id;
sort(p,p+n+1,cmp3);
for(int i=0;i<n;i++)
if(p[i].x==p[i+1].x)
t3[p[i].id]=p[i+1].id;
sort(p,p+n+1,cmp4);
for(int i=0;i<=n;i++)
rl[p[i].id]=i;
memset(f,200,sizeof(f));
f[rl[0]]=0;
for(int i=0;i<=n;i=r[i]+1)
{
for(l[i]=r[i]=i;r[i]<n&&p[r[i]+1].y==p[r[i]].y;++r[i]);
for(int j=l[i];++j<=r[i];)
l[j]=l[i],r[j]=r[i];
lf[l[i]]=-1e9;
for(int j=l[i];++j<=r[i];)
lf[j]=max(lf[j-1],f[j-1]);
rf[r[i]]=-1e9;
for(int j=r[i];--j>=l[i];)
rf[j]=max(rf[j+1],f[j+1]);
for(int j=l[i];j<=r[i];j++)
{
ff[j]=max(f[j],max(lf[j]+j-l[i],rf[j]+r[i]-j));
if(t1[p[j].id])
jia(rl[t1[p[j].id]],j);
if(t2[p[j].id])
jia(rl[t2[p[j].id]],j);
if(t3[p[j].id])
jia(rl[t3[p[j].id]],j);
if(ff[j]>ans)
ans=ff[j],v.clear();
if(ff[j]==ans)
v.push_back(j);
}
}
printf("%d\n",ans);
prin(v[0]);
for(int i=an-1;i>=1;i--)
printf("%d ",p[a[i]].id);
puts("");
for(int i=0;i<v.size();i++)
dfs(v[i]);
for(int i=0;i<=n;i++)
wk(n+1,i,0,1e9),wk(i,n+2,0,1e9);
for(int i=0;i<=n;i++)
{
if(c[i]>0)
ins(s,i,c[i]);
else
ins(i,t,-c[i]);
}
int la0=h[n+1],la1=h[n+2];
ins(n+2,n+1,1e9);
dinic();
int ans=e[cnt].va;//cerr<<ans<<endl;
h[n+1]=la0,h[n+2]=la1;
s=n+2,t=n+1;
printf("%d\n",ans-dinic());
return 0;
}

bzoj 4200: [Noi2015]小园丁与老司机【dp+有上下界最小流】的更多相关文章

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

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

  2. BZOJ4200 NOI2015小园丁与老司机(动态规划+上下界网络流)

    一看上去就是一个二合一的题.那么先解决第一部分求最优路线(及所有可能在最优路线上的线段). 由于不能往下走,可以以y坐标作为阶段.对于y坐标不同的点,我们将可以直接到达的两点连边,显然这样的边的个数是 ...

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

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

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

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

  5. [NOI2015]小园丁与老司机(DP+上下界最小流)

    由于每行点的个数不超过1000,所以行内DP可以使用$O(n^2)$算法. 先找到每个点所能直接到达的所有点(x,y,x+y或x-y相同),用排序实现. 第一问:以行为阶段,对于每行,暴力枚举最有路径 ...

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

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

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

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

  8. [Noi2015]小园丁和老司机

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有n棵许愿树,编号1,2,3,…,n,每棵树可以看作平面上的一个点,其中 ...

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

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

随机推荐

  1. 关于myeclipse缓存问题

    昨天在部署项目的时候发现,刚检出的项目jdk竟然不是1.6版本的了,而是新的(在此之前每次检出项目都会重新设置一下jdk),如图所示: 当时还在想,真好,以后就不用配置了,但是随之而来的是一个重大问题 ...

  2. 云计算系列——HIVE1.2.1 环境搭建

    hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行. 其优点是学习成本低,可以通过 ...

  3. ZFIND_ENHANCEMENT(找增强点-新)

    REPORT ZFIND_ENHANCEMENT. *&-------------------------------------------------------------------- ...

  4. assign,copy,strong,weak,nonatomic的具体理解

    例子: NSString *houseOfMM = [[NSString alloc] initWithString:'MM的三室两厅']; 上面一段代码会执行以下两个动作:  1 在堆上分配一段内存 ...

  5. LVS的体系结构

    LVS集群的体系结构 章文嵩 (wensong@linux-vs.org) 转自LVS官方资料 2002 年 4 月 本文主要介绍了LVS集群的体系结构.先给出LVS集群的通用体系结构,并讨论了其的设 ...

  6. CSS控制文本的长度,超过一行显示省略号

    代码如下: <div style="width:100px;height:20px;text-overflow:ellipsis; white-space:nowrap; overfl ...

  7. bzoj4670: 佛罗里达

    这题直接随机化+贪心就可以爆踩过去,我加了个退火增加容错率而已....其实你随机的次数够多根本不需要... 然后来自肉丝哥哥的正经做法: 先钦定D(A)>D(B),那么可以枚举D(A),然后再去 ...

  8. Looksery Cup 2015 C. The Game Of Parity —— 博弈

    题目链接:http://codeforces.com/problemset/problem/549/C C. The Game Of Parity time limit per test 1 seco ...

  9. PHP上传文件时,文件过大$_FILES为空

    在php中判断上传文件的大小,但是文件一但过大,print_r($_FILES);的值就变为null了,有时候大家会遇到这么一个问题,上传小文件时,PHP能正常获取到,但是文件一超过8M就变为空了,我 ...

  10. SqlServer--学习触发器

    触发器是一种特殊的存储过程,一种不能被显式执行,而必须依附于一个事件的过程 主要作用:自动化操作;减少手动操作以及出错的几率. 触发器分类:DML(Data Manipulation Language ...