[UOJ] #217. 【UNR #1】奇怪的线段树
题解见大佬博客
我的丑陋代码:
#include<cstdio> #include<cstring> #include<cstdlib> inline int read() { int x;char c; while((c=getchar())<'0'||c>'9'); for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0'; return x; } #define MN 8000 #define MV 16000 #define ME 56000 #define INF 0x3FFFFFFF struct edge{int nx,t,l,w;}e[ME*2+5]; int S=MV+1,T=MV+2,h[MV+5],en=1,d[MV+5],q[MV+5],qn,c[MV+5]; int cnt=1,L[MN+5],R[MN+5],u[MN+5],z[MN+5],fa[MN+5]; inline void ins(int x,int y,int l,int w) { e[++en]=(edge){h[x],y,l,w};h[x]=en; e[++en]=(edge){h[y],x,0,0};h[y]=en; } bool build(int k,int l,int r) { u[k]=read(); if(k>1&&u[k]&&!u[fa[k]])exit(0*puts("OwO")); if(l<r) { int mid; fa[L[k]=++cnt]=k;build(L[k],l,mid=read()); fa[R[k]=++cnt]=k;build(R[k],mid+1,r); z[L[k]]=R[k]; ins(k,L[k],0,INF); } L[k]=l;R[k]=r; } bool bfs() { int i,j; memset(d,0,sizeof(d)); for(d[q[i=qn=0]=S]=1;i<=qn;++i)for(j=c[q[i]]=h[q[i]];j;j=e[j].nx) if(e[j].w&&!d[e[j].t])d[q[++qn]=e[j].t]=d[q[i]]+1; return d[T]; } int dfs(int x,int r) { if(x==T)return r; int k,u=0; for(int&i=c[x];i;i=e[i].nx)if(e[i].w&&d[e[i].t]==d[x]+1) { k=dfs(e[i].t,r-u<e[i].w?r-u:e[i].w); u+=k;e[i].w-=k;e[i^1].w+=k; if(u==r)return u; } return d[x]=0,u; } int main() { int n=read(),i,j; build(1,1,n); for(i=1;i<2*n;++i)if(u[i]) { ins(S,i,0,INF); for(j=i;++j<2*n;)if(L[i]<=L[j]&&R[i]>=R[j]&&u[j])u[i]=0; ins(i,i+2*n,u[i],INF); ins(i+2*n,T,0,INF); for(j=i;++j<2*n;)if(R[i]+1==L[j]&&z[i]!=j){ins(i+2*n,j,0,INF);break;} } for(i=1;i<=T;++i)for(j=h[i];j;j=e[j].nx)d[i]-=e[j].l,d[e[j].t]+=e[j].l,e[j].w-=e[j].l; for(S+=2,T+=2,i=1;i<S;++i) { if(d[i]<0)ins(i,T,0,-d[i]); if(d[i]>0)ins(S,i,0,d[i]); } while(bfs())dfs(S,INF); ins(T-2,S-2,0,INF); while(bfs())dfs(S,INF); for(i=h[S-2];i;i=e[i].nx)if(e[i].t==T-2)printf("%d",e[i].w); }