bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)
这该死的码农题……
题解在这儿->这里
- //minamoto
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- #define inf 0x3f3f3f3f
- using namespace std;
- #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
- char buf[<<],*p1=buf,*p2=buf;
- inline int read(){
- #define num ch-'0'
- char ch;bool flag=;int res;
- while(!isdigit(ch=getc()))
- (ch=='-')&&(flag=true);
- for(res=num;isdigit(ch=getc());res=res*+num);
- (flag)&&(res=-res);
- #undef num
- return res;
- }
- const int N=;
- int n,jsx,jsy,js1,js2;
- struct node{int x,y,b1,b2,id;}p[N];
- int bx[N],by[N],bb1[N],bb2[N];
- int up[N],lup[N],rup[N],f[N],Tx[N],Tb1[N],Tb2[N],bj[N],tx[N],ty[N],gup[N],bup[N];
- bool cmpy(node a,node b){return a.y>b.y;}
- bool cmpx(node a,node b){return a.x<b.x;}
- vector<int> iny[N];
- void prework(){
- sort(bx+,bx++n),sort(by+,by++n);
- sort(bb1+,bb1++n),sort(bb2+,bb2++n);
- jsx=unique(bx+,bx++n)-bx-;
- jsy=unique(by+,by++n)-by-;
- js1=unique(bb1+,bb1++n)-bb1-;
- js2=unique(bb2+,bb2++n)-bb2-;
- for(int i=;i<=n;++i){
- p[i].x=lower_bound(bx+,bx++jsx,p[i].x)-bx,tx[i]=p[i].x;
- p[i].y=lower_bound(by+,by++jsy,p[i].y)-by,ty[i]=p[i].y;
- p[i].b1=lower_bound(bb1+,bb1++js1,p[i].b1)-bb1;
- p[i].b2=lower_bound(bb2+,bb2++js2,p[i].b2)-bb2;
- }
- sort(p+,p++n,cmpy);
- for(int i=;i<=n;++i){
- int k=p[i].id;
- up[k]=Tx[p[i].x],lup[k]=Tb1[p[i].b1],rup[k]=Tb2[p[i].b2];
- Tx[p[i].x]=Tb1[p[i].b1]=Tb2[p[i].b2]=k;
- }
- sort(p+,p++n,cmpx);
- for(int i=;i<=n;++i)
- iny[p[i].y].push_back(p[i].id);
- }
- void print(int num){
- int y=ty[num],sz=iny[y].size(),nxt=bj[num];
- if(num!=n) printf("%d ",num);
- if(tx[nxt]<tx[num]){
- for(int i=;i<sz;++i)
- if(tx[iny[y][i]]>tx[num]) printf("%d ",iny[y][i]);
- for(int i=sz-;~i;--i)
- if(tx[iny[y][i]]<tx[num]&&tx[iny[y][i]]>=tx[nxt]) printf("%d ",iny[y][i]);
- }
- else if(tx[nxt]>tx[num]){
- for(int i=sz-;~i;--i)
- if(tx[iny[y][i]]<tx[num]) printf("%d ",iny[y][i]);
- for(int i=;i<sz;++i)
- if(tx[iny[y][i]]>tx[num]&&tx[iny[y][i]]<=tx[nxt]) printf("%d ",iny[y][i]);
- }
- if(bup[nxt]) print(bup[nxt]);
- }
- void work1(){
- prework();
- for(int y=jsy;y;--y){
- int kmx=,kbj=,sz=iny[y].size();
- for(int i=;i<sz;++i){
- int k=iny[y][i];
- if(up[k]&&f[up[k]]>gup[k]) gup[k]=f[up[k]],bup[k]=up[k];
- if(lup[k]&&f[lup[k]]>gup[k]) gup[k]=f[lup[k]],bup[k]=lup[k];
- if(rup[k]&&f[rup[k]]>gup[k]) gup[k]=f[rup[k]],bup[k]=rup[k];
- f[k]=kmx,bj[k]=kbj;
- if(sz-i+gup[k]>kmx) kmx=sz-i+gup[k],kbj=k;
- }
- kmx=kbj=;
- for(int i=sz-;~i;--i){
- int k=iny[y][i];
- if(kmx>f[k]) f[k]=kmx,bj[k]=kbj;
- if(gup[k]+>f[k]) f[k]=gup[k]+,bj[k]=k;
- if(i++gup[k]>kmx) kmx=i++gup[k],kbj=k;
- }
- }
- printf("%d\n",f[n]-),print(n),puts("");
- }
- int S,T,s,t,ans,tot=;
- int ok[N],du[N],cur[N],head[N],Next[N*],ver[N*],edge[N*],dep[N];
- queue<int> q;
- inline void adde(int u,int v,int e){
- ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
- ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
- }
- inline void add(int u,int v){
- for(int i=head[u];i;i=Next[i]) if(ver[i]==v) return;
- ok[v]=,++du[v],--du[u],adde(u,v,inf);
- }
- void calc(int y,int i){
- int sz=iny[y].size(),num=iny[y][i];
- for(int j=;j<i;++j){
- int k=iny[y][j];
- if(up[k]&&f[up[k]]+sz-j==f[num]) add(k,up[k]);
- if(lup[k]&&f[lup[k]]+sz-j==f[num]) add(k,lup[k]);
- if(rup[k]&&f[rup[k]]+sz-j==f[num]) add(k,rup[k]);
- }
- for(int j=i+;j<sz;++j){
- int k=iny[y][j];
- if(up[k]&&f[up[k]]+j+==f[num]) add(k,up[k]);
- if(lup[k]&&f[lup[k]]+j+==f[num]) add(k,lup[k]);
- if(rup[k]&&f[rup[k]]+j+==f[num]) add(k,rup[k]);
- }
- if(up[num]&&f[up[num]]+==f[num]) add(num,up[num]);
- if(lup[num]&&f[lup[num]]+==f[num]) add(num,lup[num]);
- if(rup[num]&&f[rup[num]]+==f[num]) add(num,rup[num]);
- }
- void build(){
- ok[n]=;
- for(int y=;y<=jsy;++y){
- int sz=iny[y].size();
- for(int i=;i<sz;++i) if(ok[iny[y][i]]) calc(y,i);
- }
- }
- bool bfs(){
- while(!q.empty()) q.pop();
- for(int i=;i<=n+;++i) cur[i]=head[i],dep[i]=-;
- q.push(S),dep[S]=;
- while(!q.empty()){
- int u=q.front();q.pop();
- for(int i=head[u];i;i=Next[i]){
- int v=ver[i];
- if(dep[v]<&&edge[i]){
- dep[v]=dep[u]+,q.push(v);
- if(v==T) return true;
- }
- }
- }
- return false;
- }
- int dfs(int u,int limit){
- if(u==T||!limit) return limit;
- int flow=,f;
- for(int i=cur[u];i;cur[u]=i=Next[i]){
- int v=ver[i];
- if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
- flow+=f,limit-=f;
- edge[i]-=f,edge[i^]+=f;
- if(!limit) break;
- }
- }
- if(!flow) dep[u]=-;
- return flow;
- }
- void work2(){
- build();
- s=n+,t=n+,S=n+,T=n+;
- for(int i=;i<=n;++i)
- du[i]>?ans+=du[i],adde(S,i,du[i]):adde(i,T,-du[i]);
- while(bfs()) ans-=dfs(S,inf);
- printf("%d\n",ans);
- }
- int main(){
- //freopen("testdata.in","r",stdin);
- n=read();
- for(int i=;i<=n;++i){
- bx[i]=p[i].x=read(),by[i]=p[i].y=read();
- bb1[i]=p[i].b1=p[i].y-p[i].x,bb2[i]=p[i].b2=p[i].x+p[i].y;
- p[i].id=i;
- }
- ++n,p[n].id=n;
- work1(),work2();
- return ;
- }
bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)的更多相关文章
- [BZOJ4200][Noi2015]小园丁与老司机
4200: [Noi2015]小园丁与老司机 Time Limit: 20 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 106 Solved ...
- UOJ#132&bzoj4200[Noi2015]小园丁与老司机
看,这是一个传送门 Part A 把坐标离散化,按照纵坐标为第一关键字,横坐标为第二关键字排序 以$f_i$记录来到$i$这个点最多经过点数,那么答案显而易见就是$f_i$加上该层点数 转移的话就是分 ...
- BZOJ4200 NOI2015小园丁与老司机(动态规划+上下界网络流)
一看上去就是一个二合一的题.那么先解决第一部分求最优路线(及所有可能在最优路线上的线段). 由于不能往下走,可以以y坐标作为阶段.对于y坐标不同的点,我们将可以直接到达的两点连边,显然这样的边的个数是 ...
- [UOJ#132][BZOJ4200][luogu_P2304][NOI2015]小园丁与老司机
[UOJ#132][BZOJ4200][luogu_P2304][NOI2015]小园丁与老司机 试题描述 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 \(n\) 棵许愿 ...
- 【BZOJ4200】[Noi2015]小园丁与老司机 DP+最小流
[BZOJ2839][Noi2015]小园丁与老司机 Description 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2, ...
- luogu P2304 [NOI2015]小园丁与老司机 dp 上下界网络流
LINK:小园丁与老司机 苦心人 天不负 卧薪尝胆 三千越甲可吞吴 AC的刹那 真的是泪目啊 很久以前就写了 当时记得特别清楚 写到肚子疼.. 调到胳膊疼.. ex到根不不想看的程度. 当时wa了 一 ...
- uoj132/BZOJ4200/洛谷P2304 [Noi2015]小园丁与老司机 【dp + 带上下界网络流】
题目链接 uoj132 题解 真是一道大码题,,,肝了一个上午 老司机的部分是一个\(dp\),观察点是按\(y\)分层的,而且按每层点的上限来看可以使用\(O(nd)\)的\(dp\),其中\(d\ ...
- BZOJ4200 & 洛谷2304 & UOJ132:[NOI2015]小园丁与老司机——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4200 https://www.luogu.org/problemnew/show/P2304 ht ...
- 【bzoj4200】[Noi2015]小园丁与老司机 STL-map+dp+有上下界最小流
题目描述 小园丁 Mr. S 负责看管一片田野,田野可以看作一个二维平面.田野上有 nn 棵许愿树,编号 1,2,3,…,n1,2,3,…,n,每棵树可以看作平面上的一个点,其中第 ii 棵树 (1≤ ...
随机推荐
- myod中遇到的问题
一.准备工作 首先在编程之前遇到的第一个问题就是要了解需要编出一个怎样的代码,了解od -tx -tc的具体意思,并观察其输出结果. -tc代表着输出ASCII字符,而-tx则是代表着输出ASCII字 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第四周作业
本次的实验是使用gdb跟踪调试内核从start_kernel到init进程启动,并分析启动的过程. 1.首先是在实验楼虚拟机上进行调试跟踪的过程. cd LinuxKernel qemu -kerne ...
- ACM学习历程—UESTC 1222 Sudoku(矩阵)(2015CCPC H)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目大意就是构造一个行列和每个角的2*2都是1234的4*4矩阵. 用dfs暴力搜索,不过需要每一步进 ...
- ACM学习历程—HDU 5012 Dice(ACM西安网赛)(bfs)
Problem Description There are 2 special dices on the table. On each face of the dice, a distinct num ...
- Django中的事务(Transaction)管理
Django默认的事务行为 默认情况下,在Django中事务是自动提交的.当我们运行Django内置的模板修改函数时,例如调用model.save()或model.delete()时,事务将被立即提交 ...
- 【转】 Pro Android学习笔记(七二):HTTP服务(6):HttpURLConnection
目录(?)[-] Http Get的使用方式 基础小例子 Cookie的使用 重定向 HTTP POST的小例子 基础小例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载 ...
- hashCode之二--Java:重写equals()和hashCode()
以下内容总结自<Effective Java>. 1.何时需要重写equals() 当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念). 2.设计equals() [1]使用in ...
- ss1
首先,对系统来一次升级,以解决一些莫名其妙的依赖问题. sudo yum update 然后安装Python-pip. sudo yum -y install python-pip 注意,通过yum包 ...
- python操作sql server2008 pyodbc
使用Python通过PyODBC连接数据的注意事项 今天使者用PyODBC连接数据库,试了很久才出来,现把一些心得体会和大家分享! 一.PyODBC的下载地址: http://code.google. ...
- 2017清北学堂(提高组精英班)集训笔记——动态规划Part3
现在是晚上十二点半,好累(无奈脸),接着给各位——也是给自己,更新笔记吧~ 序列型状态划分: 经典例题:乘积最大(Luogu 1018) * 设有一个长度为 N 的数字串,要求选手使用 K 个乘号将它 ...