UOJ 217 奇怪的线段树
http://uoj.ac/problem/217
题意就不X了,思路在这:
居然一开始把sap里面的mn设置为inf了,我是傻逼。。
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x3f3f3f3f int go[200005],first[200005],next[200005],flow[200005],op[200005],dis[200005],cnt[200005]; int tot,S,T,t,s,sz,son[200005],du[200005],n,nodes; bool flag; int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } void insert(int x,int y,int z){ tot++; go[tot]=y; next[tot]=first[x]; first[x]=tot; flow[tot]=z; } void add(int x,int y,int z){ insert(x,y,z);op[tot]=tot+1; insert(y,x,0);op[tot]=tot-1; } void add(int x,int y,int low,int high){ int F=high-low; add(x,y,F);du[x]-=low;du[y]+=low; } int build(int l,int r,int op){ int k=++sz; add(s,k,0,inf);add(k+2*n-1,t,0,inf); add(4*n-2+l,k,0,inf);if (op&&r<n) add(k+2*n-1,4*n-2+r+1,0,inf); if (!op) add(5*n-2+l,k,0,inf); if (!op&&r<n) add(k+2*n-1,5*n-2+r+1,0,inf); int x=read(); if (l==r){ son[k]=x; return x; } int mid=read(); int p=build(l,mid,0),q=build(mid+1,r,1); if (p||q){ if (!x) flag=0; son[k]=2; return 1; } return son[k]=x; } int dfs(int x,int f){ if (x==T) return f; int mn=nodes,sum=0; for (int i=first[x];i;i=next[i]){ int pur=go[i]; if (dis[pur]+1==dis[x]&&flow[i]){ int F=std::min(flow[i],f-sum); int save=dfs(pur,F); sum+=save; flow[i]-=save; flow[op[i]]+=save; if (sum==f||dis[S]>=nodes) return sum; } if (flow[i]) mn=std::min(mn,dis[pur]); } if (sum==0){ cnt[dis[x]]--; if (cnt[dis[x]]==0){ dis[S]=nodes; }else{ dis[x]=mn+1; cnt[dis[x]]++; } } return sum; } int mxflow(){ int res=0,tim=0; while (dis[S]<nodes){ tim++; res+=dfs(S,inf); } return res; } int main(){ n=read(); s=0;t=6*n-1; flag=1; build(1,n,0); if (!flag) {puts("OwO");return 0;} for (int i=1;i<=sz;i++) if (son[i]==1) add(i,i+sz,1,inf); else if (son[i]==2) add(i,i+sz,0,inf); S=t+1,T=S+1;nodes=T+1; for (int i=s;i<=t;i++) if (du[i]>0) add(S,i,du[i]); else if (du[i]<0) add(i,T,-du[i]); int ans1=mxflow(); memset(dis,0,sizeof dis); memset(cnt,0,sizeof cnt); add(t,s,inf); int ans=mxflow(); printf("%d\n",ans); }