[下界最小流] UNR #1 奇怪的线段树

来源:互联网 发布:有哪些动画培训班知乎 编辑:程序博客网 时间:2024/06/11 08:39

奇怪的线段树


考试时硬是没想出怎么最小流建图


#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<cstring>#define cl(x) memset(x,0,sizeof(x))#define inf 1<<30using namespace std;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc());}const int oo=1<<30;namespace DINIC{#define V G[p].v#define cl(x) memset(x,0,sizeof(x))const int M=100000+5;const int N=60000+5;struct edge{int u,v,f;int next;};edge G[M];int head[N],num=1;inline void add(int u,int v,int f,int p){G[p].u=u; G[p].v=v; G[p].f=f; G[p].next=head[u]; head[u]=p;}inline void link(int u,int v,int f){add(u,v,f,num+=2); add(v,u,0,num^1);}int S,T;int Que[N],l,r;int dis[N];inline bool bfs(){int u;memset(dis,-1,sizeof(dis)); cl(Que); l=r=-1;dis[S]=1; Que[++r]=S;while (l<r){u=Que[++l];for (int p=head[u];p;p=G[p].next)if (G[p].f && dis[V]==-1){dis[V]=dis[u]+1;Que[++r]=V;if (V==T) return true;}}return false;} int minimum;int cur[N];inline bool dfs(int u,int mini){if (u==T) { minimum=mini; return true; }for (int p=cur[u];p;p=G[p].next){cur[u]=p;if (G[p].f && dis[V]==dis[u]+1 && dfs(V,min(mini,G[p].f))){G[p].f-=minimum; G[p^1].f+=minimum;return true;}}dis[u]=-1;return false;}inline int Dinic(){int ret=0;while (bfs()){memcpy(cur,head,sizeof(cur));while (dfs(S,oo)) ret+=minimum;}return ret;}inline void clear(){cl(G); cl(head); num=1;}}int deg[50005];const int N=4005;int mn;int root,ncnt=0;int ls[N<<2],rs[N<<2];int lp[N<<2],rp[N<<2],mid[N<<2],clr[N<<2];int idx[N<<2];int isl[N<<2],isr[N<<2];inline int Build(int &x,int l,int r){x=++ncnt;lp[ncnt]=l; rp[ncnt]=r; read(clr[ncnt]);int f=0;if (l!=r){read(mid[x]);f|=Build(ls[x],l,mid[x]);f|=Build(rs[x],mid[x]+1,r);isl[ls[x]]=1; isr[rs[x]]=1;}if (!f && clr[x]==1)clr[x]=2;if (f && clr[x]==0)printf("OwO\n"),exit(0);if (clr[x]) f|=1;return f;}#define pp(x) (2*ncnt+(x))int Cnt,Minc;int main(){using namespace DINIC;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(mn);Build(root,1,mn);int s=2*ncnt+mn+1,t=2*ncnt+mn+2;S=2*ncnt+mn+3; T=2*ncnt+mn+4;for (int i=1;i<=ncnt;i++){int v1=2*i-1,v2=2*i;link(pp(lp[i]),v1,oo);if (isr[i] && rp[i]<mn) link(v2,pp(rp[i]+1),oo);if (isl[i]){for (int j=1;j<=ncnt;j++)if (isl[j] && rp[i]+1==lp[j])link(v2,2*j-1,oo);}link(s,v1,oo);link(v2,t,oo);if (clr[i]) link(v1,v2,oo);if (clr[i]==2)deg[v1]--,deg[v2]++;}for (int i=1;i<=2*ncnt;i++)if (deg[i]>0)Cnt+=deg[i],link(S,i,deg[i]);else if (deg[i]<0)link(i,T,-deg[i]);Minc=Dinic();Minc=Cnt-Minc;printf("%d\n",Minc);return 0;}

0 0