bzoj3681: Arietta(网络流)
Posted bztminamoto
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3681: Arietta(网络流)相关的知识,希望对你有一定的参考价值。
主席树优化建图?
然而我连代码都看不懂
贴个题解好了->这里
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<vector> 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=10005; 22 int head[N*80],dep[N*80],cur[N*80],ver[N*240],edge[N*240],Next[N*240],tot=1; 23 int fa[N],L[N*80],R[N*80],sz[N],son[N],rt[N],v[N]; 24 queue<int> q;vector<int> ch[N];int S,T,cnt,n,m; 25 inline void add(int u,int v,int e){ 26 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 27 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0; 28 } 29 bool bfs(){ 30 while(!q.empty()) q.pop(); 31 for(int i=S;i<=T;++i) cur[i]=head[i]; 32 memset(dep,-1,sizeof(dep)); 33 q.push(S),dep[S]=0; 34 while(!q.empty()){ 35 int u=q.front();q.pop(); 36 for(int i=head[u];i;i=Next[i]){ 37 int v=ver[i]; 38 if(dep[v]<0&&edge[i]){ 39 dep[v]=dep[u]+1,q.push(v); 40 if(v==T) return true; 41 } 42 } 43 } 44 return false; 45 } 46 int dfs(int u,int limit){ 47 if(u==T||!limit) return limit; 48 int flow=0,f; 49 for(int i=cur[u];i;cur[u]=i=Next[i]){ 50 int v=ver[i]; 51 if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){ 52 flow+=f,limit-=f; 53 edge[i]-=f,edge[i^1]+=f; 54 if(!limit) break; 55 } 56 } 57 if(!flow) dep[u]=-1; 58 return flow; 59 } 60 int dinic(){ 61 int flow=0; 62 while(bfs()) flow+=dfs(S,inf); 63 return flow; 64 } 65 void update(int &p,int x,int l,int r,int a,int b){ 66 p=++cnt; 67 if(l==r){ 68 add(p+n,b,inf); 69 if(x) add(p+n,x+n,inf); 70 return; 71 } 72 int mid=l+r>>1; 73 if(a<=mid) R[p]=R[x],update(L[p],L[x],l,mid,a,b); 74 else L[p]=L[x],update(R[p],R[x],mid+1,r,a,b); 75 } 76 inline void getall(int x,int y){ 77 update(rt[x],rt[x],1,n,v[y],y); 78 for(int i=0,s=ch[y].size();i<s;++i) getall(x,ch[y][i]); 79 } 80 void DFS(int u){ 81 sz[u]=1; 82 for(int i=0,s=ch[u].size();i<s;++i){ 83 int v=ch[u][i]; 84 DFS(v),sz[u]+=sz[v]; 85 if(sz[v]>sz[son[u]]) son[u]=v; 86 } 87 update(rt[u],rt[son[u]],1,n,v[u],u); 88 for(int i=0,s=ch[u].size();i<s;++i) 89 if(ch[u][i]!=son[u]) getall(u,ch[u][i]); 90 } 91 void query(int p,int l,int r,int ql,int qr,int x){ 92 if(!p) return; 93 if(ql<=l&&qr>=r) return (void)(add(x+n,p+n,inf)); 94 int mid=l+r>>1; 95 if(ql<=mid) query(L[p],l,mid,ql,qr,x); 96 if(qr>mid) query(R[p],mid+1,r,ql,qr,x); 97 } 98 int main(){ 99 //freopen("testdata.in","r",stdin); 100 n=read(),m=read(); 101 for(int i=2;i<=n;++i) fa[i]=read(),ch[fa[i]].push_back(i); 102 for(int i=1;i<=n;++i) v[i]=read(); 103 DFS(1); 104 S=0; 105 for(int i=1;i<=cnt;++i){ 106 if(L[i]) add(i+n,L[i]+n,inf); 107 if(R[i]) add(i+n,R[i]+n,inf); 108 } 109 for(int i=1;i<=m;++i){ 110 int l=read(),r=read(),p=read(),t=read(); 111 add(S,(++cnt)+n,t); 112 query(rt[p],1,n,l,r,cnt); 113 } 114 T=cnt+n+1; 115 for(int i=1;i<=n;++i) add(i,T,1); 116 printf("%d ",dinic()); 117 return 0; 118 }
以上是关于bzoj3681: Arietta(网络流)的主要内容,如果未能解决你的问题,请参考以下文章