题目链接

洛谷的,有点不清楚。

建议去UOJ上或LOJ切了再搬运。

luogu

UOJ

LOJ

sol

老司机是一个显然的\(dp\)。

发现是个\(DAG\),可以愉快的按\(y\)坐标排序转移。

发现五个移动不好算,那么设\(g[i]\)表示从\(i\)点开始前往\(y\)坐标比\(i\)大的点的最多到的许愿树个数,\(f[i]\)表示从\(i\)进入\(y\)坐标能够最多到的许愿树个数。

先算这一层所有的\(g\),再算\(f\)。分两种情况,入点在出点右边或左边,只要从前往后\(dp\)一次,从后往前\(dp\)一次就\(ok\)了。

\(g\)的话维护三个桶,分别代表\(x+y\),\(x-y\),\(x\)的桶,用\(f\)转移\(g\)。

因为如果\(i<j,y_i==y_j\),从\(i\)点进\(j\)点出可以先往左走,再往右走到\(j\)离开,所以算的时候贡献是\(y\)坐标为\(y_i\)的点的个数减去\(j\)和它右边的点的个数,那么我们可以一开始减掉,最后算答案的时候加上\(y\)坐标为\(y_i\)的点的个数。这显然是个前缀或后缀\(max\)的优化\(dp\)。

那么我们得到了\(20\ pts\ QAQ\)。

\(40\)分的话也好做,\(dfs\)一条路出来,你怎么转移的就倒过来怎么找路径,具体可以看代码。

\(100\)分不难,按\(40\)分的思路去找所有的边,只是不\(dfs\)而是遍历每个可能出现的点。

然后就是个很裸的上下界最小流了。

听\(litble\)说直接写会\(TLE\),所以我就没写最裸的,加了个优化。

因为你肯定有解,并且\(S\)和\(T\)到每个点都有\(inf\)的边,所以我们不管它们,直接建超级源汇连原图,跑出来最大流就是图本生可以减少的流量。

减掉就\(ok\)了。

不算网络流模板这道题还挺短的\(QAQ\)。

#include<map>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#define gt getchar()
#define ll long long
#define Set(p,v) memset(p,v,sizeof(p))
#define Cpy(p,v) memcpy(p,v,sizeof(p))
inline int in()
{int k=0,p=1;char ch=gt;while(!isdigit(ch)&&ch!='-')ch=gt;if(ch=='-')p=0,ch=gt;while(isdigit(ch))k=k*10+ch-'0',ch=gt;return p?k:-k;
}
inline int min(const int &a,const int &b){return a<b?a:b;}
inline int max(const int &a,const int &b){return a>b?a:b;}
const int inf=0x7fffffff;
class Graph
{
private:static const int N=400005,M=1000005;int s,t;int dis[N];int pre[N],pr[N],o[N],cur[N];int head[N],nxt[M],to[M],cap[M];double w[M];
public:int n,cnt;inline void init(int nn,int ss,int tt){n=nn,s=ss,t=tt;cnt=-1;Set(head,-1);}inline void add_Edge(int u,int v,int cc,int ww){to[++cnt]=v,cap[cnt]=cc,w[cnt]=ww,nxt[cnt]=head[u],head[u]=cnt;}inline void add(int u,int v,int cc,int ww=0){add_Edge(u,v,cc,ww),add_Edge(v,u,0,-ww);}int dfs(int u,int dist){if(u==t)return dist;for(int &i=cur[u];~i;i=nxt[i]){if(dis[to[i]]==dis[u]+1&&cap[i]!=0){int d=dfs(to[i],min(dist,cap[i]));if(d>0){cap[i]-=d;cap[i^1]+=d;return d;}}}return 0;}int bfs(){std::queue<int>Q;Set(dis,0);Q.push(s);dis[s]=1;while(!Q.empty()){int u=Q.front();Q.pop();for(int i=head[u];~i;i=nxt[i]){if(cap[i]>0&&dis[to[i]]==0){dis[to[i]]=dis[u]+1;Q.push(to[i]);}}}return dis[t]>0;}int dinic(){int res=0,d;while(bfs()){Cpy(cur,head);while((d=dfs(s,inf)))res+=d;}return res;}int spfa(){//实数流的时候务必用for给dis赋值std::queue<int>Q;Set(dis,0x3f);Set(pr,0);Set(o,0);Set(pre,0);dis[s]=0;Q.push(s);o[s]=1;while(!Q.empty()){int u=Q.front();Q.pop();o[u]=0;for(int i=head[u];~i;i=nxt[i])if(cap[i]>0&&dis[to[i]]>dis[u]+w[i]){dis[to[i]]=dis[u]+w[i];pr[to[i]]=i;pre[to[i]]=u;if(!o[to[i]])o[to[i]]=1,Q.push(to[i]);}}return pre[t]!=0;}void fyl(int &ans,int &hh){ans=hh=0;while(spfa()){int d=inf;for(int i=t;i!=s;i=pre[i])d=min(d,cap[pr[i]]);hh+=dis[t]*d;ans+=d;for(int i=t;i!=s;i=pre[i])cap[pr[i]]-=d,cap[pr[i]^1]+=d;}}int fyl(){int hh=0;while(spfa()){int d=inf;for(int i=t;i!=s;i=pre[i])d=min(d,cap[pr[i]]);hh+=dis[t]*d;for(int i=t;i!=s;i=pre[i])cap[pr[i]]-=d,cap[pr[i]^1]+=d;}return hh;}
}cx;typedef std::pair<int,int> P;
#define mk std::make_pair
#define fr first
#define sc second
const int N=50005;
int n,tot;P E[N*20];
struct point{int x,y,id;}a[N];
inline bool cmpx(point a,point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
inline bool cmpy(point a,point b){return a.y==b.y?a.x<b.x:a.y<b.y;}
inline bool cmpi(point a,point b){return a.id<b.id;}
inline void cmax(int &x,int y,int *a,int &c,int b){if(x<y)x=y,a[(c=1)-1]=b;else if(x==y)a[c++]=b;}
inline void cmax(int &x,int y){if(x<y)x=y;}
inline void Push(int x,int y){E[++tot]=mk(x,y);}namespace w1
{using std::map;map<int,int>t1,t2,t3,mp[N];int f[N],g[N],pre[N][3],L[N],R[N],TT,o[N],cnt[N];inline int calc(int u,int k){if(u==k)return g[k];if(u<k)return g[k]+k-L[k];else return g[k]+R[k]-k;}void dfs(int val,int u)//求一组最优方案{if(u==-1)return;if(u!=1)printf("%d ",a[u].id);int l=L[u],r=R[u];for(int i=l;i<=r;++i)if(calc(u,i)==val){if(u==i)return dfs(g[u]-1,pre[u][0]);if(u<i)for(int j=u-1;j>=l;--j)printf("%d ",a[j].id);else for(int j=u+1;j<=r;++j)printf("%d ",a[j].id);if(u<i)for(int j=u+1;j<=i;++j)printf("%d ",a[j].id);else for(int j=u-1;j>=i;--j)printf("%d ",a[j].id);return dfs(g[i]-1,pre[i][0]);}}void Dfs(int val,int u)//求所有边{if(u==-1||o[u])return;int l=L[u],r=R[u];o[u]=1;for(int i=l;i<=r;++i)if(calc(u,i)==val)for(int k=0;k<cnt[i];++k)if(pre[i][k]&&pre[i][k]!=-1){if(mp[i].find(k)==mp[i].end())Push(i,pre[i][k]),mp[i][k]=1;if(!o[pre[i][k]])Dfs(g[i]-1,pre[i][k]);}}void solve(){a[++n]=(point){0,0,0};std::sort(a+1,a+n+1,cmpy);for(int i=n,j;i>=1;i=j-1){for(j=i;j>1&&a[j-1].y==a[i].y;--j);for(int k=j;k<=i;++k)L[k]=j,R[k]=i;for(int k=j;k<=i;++k){int x=a[k].x,y=a[k].y;g[k]=1;pre[k][cnt[k]=0]=-1;if(t1.find(x+y)!=t1.end())cmax(g[k],f[t1[x+y]]+1,pre[k],cnt[k],t1[x+y]);if(t2.find(x-y)!=t2.end())cmax(g[k],f[t2[x-y]]+1,pre[k],cnt[k],t2[x-y]);if(t3.find( x )!=t3.end())cmax(g[k],f[t3[ x ]]+1,pre[k],cnt[k],t3[ x ]);t1[x+y]=t2[x-y]=t3[x]=k;}for(int k=j,mx=-1e9;k<=i;++k)cmax(f[k],g[k]),cmax(f[k],mx+i-j),cmax(mx,g[k]-k+j);for(int k=i,mx=-1e9;k>=j;--k)cmax(f[k],g[k]),cmax(f[k],mx+i-j),cmax(mx,g[k]-i+k);}printf("%d\n",f[1]-1);dfs(f[1],1);puts("");Dfs(f[1],1);}
}namespace w2
{int du[N];void solve(){int t=n+1,s=0,ans=0;cx.init(t+1,s,t);for(int i=1;i<=tot;++i)--du[E[i].fr],++du[E[i].sc],cx.add(E[i].fr,E[i].sc,inf);for(int i=1;i<=n;++i)if(du[i]>0)cx.add(s,i,du[i]),ans+=du[i];else if(du[i]<0)cx.add(i,t,-du[i]);printf("%d\n",ans-cx.dinic());}
}
int main()
{n=in();for(int i=1;i<=n;++i)a[i].x=in(),a[i].y=in(),a[i].id=i;w1::solve();w2::solve();return 0;
}

转载于:https://www.cnblogs.com/cx233666/p/10422031.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. iOS微信支付集成 SDK1 7 5
  2. GCD or LCM ---- 处理gcd和lcm同时出现的情况 1499D - The Number of Pairs
  3. puppet 类、模块
  4. matlab求一个方程组的系数矩阵,【求解】matlab求解非齐次方程组,但是系数矩阵是复数,求帮忙...
  5. mysql purge进程_InnoDB Purge 的工作原理?
  6. arm中的.a文件如何产生的_可变文件系统:如何在IPFS中处理文件?
  7. leetcode559. N叉树的最大深度
  8. Bower和npm有什么区别?
  9. String 源码探究
  10. 电脑c语言数字时钟代码大全,数字时钟c语言代码.doc
  11. 支付宝VS微信支付竞品分析
  12. 漫威女性电影背后所体现出来的性别观念转变
  13. php表单提交并发送邮件给某个邮箱(示例源码)
  14. 3+1活动:结交一个朋友、参与一项运动 、培养一个兴趣爱好 、阅读一本好书
  15. ueditor插入视频无法播放解决方法
  16. CVX示例库之多面体的Chebyshev中心
  17. spark性能优化(二)数据倾斜问题
  18. linux查看文档结构图,Linux之文本处理
  19. Luckily general gradient for spherical harmonics is defined
  20. 7000字详解数据指标体系建设实践

热门文章

  1. 关于Toast的一些常见操作
  2. 75.【JavaWeb-03】
  3. 石家庄地铁选站系统进度报告
  4. 弱水三千,该取几瓢饮?
  5. 星际争霸2的图形界面几乎全部使用Flash搭建?
  6. 乌班图系统重启服务器,3种重启Ubuntu服务器命令方式技巧
  7. 5分钟学会图片优化 之 七伤拳
  8. (四)HEVC基本理论——变换单元TU
  9. 计算机组成原理实验移位运算,移位运算实验
  10. html弹性布局什么意思,弹性布局display:flex是什么意思