bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)
Posted bztminamoto
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)相关的知识,希望对你有一定的参考价值。
这该死的码农题……
题解在这儿->这里
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 10 char buf[1<<21],*p1=buf,*p2=buf; 11 inline int read(){ 12 #define num ch-‘0‘ 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch==‘-‘)&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 const int N=100005; 22 int n,jsx,jsy,js1,js2; 23 struct node{int x,y,b1,b2,id;}p[N]; 24 int bx[N],by[N],bb1[N],bb2[N]; 25 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]; 26 bool cmpy(node a,node b){return a.y>b.y;} 27 bool cmpx(node a,node b){return a.x<b.x;} 28 vector<int> iny[N]; 29 void prework(){ 30 sort(bx+1,bx+1+n),sort(by+1,by+1+n); 31 sort(bb1+1,bb1+1+n),sort(bb2+1,bb2+1+n); 32 jsx=unique(bx+1,bx+1+n)-bx-1; 33 jsy=unique(by+1,by+1+n)-by-1; 34 js1=unique(bb1+1,bb1+1+n)-bb1-1; 35 js2=unique(bb2+1,bb2+1+n)-bb2-1; 36 for(int i=1;i<=n;++i){ 37 p[i].x=lower_bound(bx+1,bx+1+jsx,p[i].x)-bx,tx[i]=p[i].x; 38 p[i].y=lower_bound(by+1,by+1+jsy,p[i].y)-by,ty[i]=p[i].y; 39 p[i].b1=lower_bound(bb1+1,bb1+1+js1,p[i].b1)-bb1; 40 p[i].b2=lower_bound(bb2+1,bb2+1+js2,p[i].b2)-bb2; 41 } 42 sort(p+1,p+1+n,cmpy); 43 for(int i=1;i<=n;++i){ 44 int k=p[i].id; 45 up[k]=Tx[p[i].x],lup[k]=Tb1[p[i].b1],rup[k]=Tb2[p[i].b2]; 46 Tx[p[i].x]=Tb1[p[i].b1]=Tb2[p[i].b2]=k; 47 } 48 sort(p+1,p+1+n,cmpx); 49 for(int i=1;i<=n;++i) 50 iny[p[i].y].push_back(p[i].id); 51 } 52 void print(int num){ 53 int y=ty[num],sz=iny[y].size(),nxt=bj[num]; 54 if(num!=n) printf("%d ",num); 55 if(tx[nxt]<tx[num]){ 56 for(int i=0;i<sz;++i) 57 if(tx[iny[y][i]]>tx[num]) printf("%d ",iny[y][i]); 58 for(int i=sz-1;~i;--i) 59 if(tx[iny[y][i]]<tx[num]&&tx[iny[y][i]]>=tx[nxt]) printf("%d ",iny[y][i]); 60 } 61 else if(tx[nxt]>tx[num]){ 62 for(int i=sz-1;~i;--i) 63 if(tx[iny[y][i]]<tx[num]) printf("%d ",iny[y][i]); 64 for(int i=0;i<sz;++i) 65 if(tx[iny[y][i]]>tx[num]&&tx[iny[y][i]]<=tx[nxt]) printf("%d ",iny[y][i]); 66 } 67 if(bup[nxt]) print(bup[nxt]); 68 } 69 void work1(){ 70 prework(); 71 for(int y=jsy;y;--y){ 72 int kmx=0,kbj=0,sz=iny[y].size(); 73 for(int i=0;i<sz;++i){ 74 int k=iny[y][i]; 75 if(up[k]&&f[up[k]]>gup[k]) gup[k]=f[up[k]],bup[k]=up[k]; 76 if(lup[k]&&f[lup[k]]>gup[k]) gup[k]=f[lup[k]],bup[k]=lup[k]; 77 if(rup[k]&&f[rup[k]]>gup[k]) gup[k]=f[rup[k]],bup[k]=rup[k]; 78 f[k]=kmx,bj[k]=kbj; 79 if(sz-i+gup[k]>kmx) kmx=sz-i+gup[k],kbj=k; 80 } 81 kmx=kbj=0; 82 for(int i=sz-1;~i;--i){ 83 int k=iny[y][i]; 84 if(kmx>f[k]) f[k]=kmx,bj[k]=kbj; 85 if(gup[k]+1>f[k]) f[k]=gup[k]+1,bj[k]=k; 86 if(i+1+gup[k]>kmx) kmx=i+1+gup[k],kbj=k; 87 } 88 } 89 printf("%d ",f[n]-1),print(n),puts(""); 90 } 91 int S,T,s,t,ans,tot=1; 92 int ok[N],du[N],cur[N],head[N],Next[N*10],ver[N*10],edge[N*10],dep[N]; 93 queue<int> q; 94 inline void adde(int u,int v,int e){ 95 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 96 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0; 97 } 98 inline void add(int u,int v){ 99 for(int i=head[u];i;i=Next[i]) if(ver[i]==v) return; 100 ok[v]=1,++du[v],--du[u],adde(u,v,inf); 101 } 102 void calc(int y,int i){ 103 int sz=iny[y].size(),num=iny[y][i]; 104 for(int j=0;j<i;++j){ 105 int k=iny[y][j]; 106 if(up[k]&&f[up[k]]+sz-j==f[num]) add(k,up[k]); 107 if(lup[k]&&f[lup[k]]+sz-j==f[num]) add(k,lup[k]); 108 if(rup[k]&&f[rup[k]]+sz-j==f[num]) add(k,rup[k]); 109 } 110 for(int j=i+1;j<sz;++j){ 111 int k=iny[y][j]; 112 if(up[k]&&f[up[k]]+j+1==f[num]) add(k,up[k]); 113 if(lup[k]&&f[lup[k]]+j+1==f[num]) add(k,lup[k]); 114 if(rup[k]&&f[rup[k]]+j+1==f[num]) add(k,rup[k]); 115 } 116 if(up[num]&&f[up[num]]+1==f[num]) add(num,up[num]); 117 if(lup[num]&&f[lup[num]]+1==f[num]) add(num,lup[num]); 118 if(rup[num]&&f[rup[num]]+1==f[num]) add(num,rup[num]); 119 } 120 void build(){ 121 ok[n]=1; 122 for(int y=1;y<=jsy;++y){ 123 int sz=iny[y].size(); 124 for(int i=0;i<sz;++i) if(ok[iny[y][i]]) calc(y,i); 125 } 126 } 127 bool bfs(){ 128 while(!q.empty()) q.pop(); 129 for(int i=1;i<=n+4;++i) cur[i]=head[i],dep[i]=-1; 130 q.push(S),dep[S]=0; 131 while(!q.empty()){ 132 int u=q.front();q.pop(); 133 for(int i=head[u];i;i=Next[i]){ 134 int v=ver[i]; 135 if(dep[v]<0&&edge[i]){ 136 dep[v]=dep[u]+1,q.push(v); 137 if(v==T) return true; 138 } 139 } 140 } 141 return false; 142 } 143 int dfs(int u,int limit){ 144 if(u==T||!limit) return limit; 145 int flow=0,f; 146 for(int i=cur[u];i;cur[u]=i=Next[i]){ 147 int v=ver[i]; 148 if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){ 149 flow+=f,limit-=f; 150 edge[i]-=f,edge[i^1]+=f; 151 if(!limit) break; 152 } 153 } 154 if(!flow) dep[u]=-1; 155 return flow; 156 } 157 void work2(){ 158 build(); 159 s=n+1,t=n+2,S=n+3,T=n+4; 160 for(int i=1;i<=n;++i) 161 du[i]>0?ans+=du[i],adde(S,i,du[i]):adde(i,T,-du[i]); 162 while(bfs()) ans-=dfs(S,inf); 163 printf("%d ",ans); 164 } 165 int main(){ 166 //freopen("testdata.in","r",stdin); 167 n=read(); 168 for(int i=1;i<=n;++i){ 169 bx[i]=p[i].x=read(),by[i]=p[i].y=read(); 170 bb1[i]=p[i].b1=p[i].y-p[i].x,bb2[i]=p[i].b2=p[i].x+p[i].y; 171 p[i].id=i; 172 } 173 ++n,p[n].id=n; 174 work1(),work2(); 175 return 0; 176 }
以上是关于bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)的主要内容,如果未能解决你的问题,请参考以下文章