bzoj3218: a + b Problem
原来我早就能过了。。。就是数组开小了。。。。
这是一个最小割的题
但是因为加了线段树优化构图变得恶心了
构图的时候需要注意的:同层的点向前建边,插入的链上的每一个点都要和当前的i位置连边
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int inf=(1<<30); struct node { int x,y,c,next; }a[2100000];int len,last[110000]; void ins(int x,int y,int c) { len++; a[len].x=x;a[len].y=y;a[len].c=c; a[len].next=last[x];last[x]=len; len++; a[len].x=y;a[len].y=x;a[len].c=0; a[len].next=last[y];last[y]=len; } int h[110000],st,ed; int list[110000]; bool bt_h() { memset(h,0,sizeof(h));h[st]=1; int head=1,tail=2;list[1]=st; while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0&&h[y]==0) { h[y]=h[x]+1; list[tail++]=y; } } head++; } return h[ed]!=0; } int findflow(int x,int f) { if(x==ed)return f; int s=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0&&h[y]==h[x]+1&&s<f) { int t=findflow(y,min(a[k].c,f-s)); s+=t;a[k].c-=t;a[k^1].c+=t; } } if(s==0)h[x]=0; return s; } //-------------------------findflow----------------------------------- int n; struct trnode { int lc,rc; }tr[2100000];int trlen,rt[51000]; int maketree(int x,int y,int l,int r,int p,int id) { if(y!=0)ins(x+ed,y+ed,inf); ins(x+ed,id,inf); if(l<r) { int mid=(l+r)/2,t; if(p<=mid) { tr[x].lc=++trlen;tr[x].rc=tr[y].rc; maketree(tr[x].lc,tr[y].lc,l,mid,p,id); } else { tr[x].lc=tr[y].lc;tr[x].rc=++trlen; maketree(tr[x].rc,tr[y].rc,mid+1,r,p,id); } } } void findroot(int now,int L,int R,int l,int r,int id) { if(now==0)return ; if(L==l&&R==r) { ins(id,now+ed,inf); return ; } int mid=(L+R)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) findroot(lc,L,mid,l,r,id); else if(mid+1<=l)findroot(rc,mid+1,R,l,r,id); else findroot(lc,L,mid,l,mid,id),findroot(rc,mid+1,R,mid+1,r,id); } struct point{int id,b,w,l,r,p;}p[51000]; int lslen,ls[51000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d",&n); st=n*2+1,ed=n*2+2; lslen=0; for(int i=1;i<=n;i++) { scanf("%d%d%d%d%d%d",&p[i].id,&p[i].b,&p[i].w,&p[i].l,&p[i].r,&p[i].p); ls[++lslen]=p[i].id,ls[++lslen]=p[i].l,ls[++lslen]=p[i].r; } sort(ls+1,ls+lslen+1); lslen=unique(ls+1,ls+lslen+1)-ls-1; len=1; for(int i=1;i<=n;i++) { p[i].id=lower_bound(ls+1,ls+lslen+1,p[i].id)-ls; p[i].l=lower_bound(ls+1,ls+lslen+1,p[i].l)-ls; p[i].r=upper_bound(ls+1,ls+lslen+1,p[i].r)-ls-1; } //-------------------------LSH---------------------------- int sum=0; trlen=0;memset(rt,0,sizeof(rt)); for(int i=1;i<=n;i++) { sum+=p[i].w+p[i].b; ins(st,i,p[i].b); ins(i,i+n,p[i].p); ins(i,ed,p[i].w); rt[i]=++trlen; maketree(rt[i],rt[i-1],1,lslen,p[i].id,i); if(i!=1)findroot(rt[i-1],1,lslen,p[i].l,p[i].r,i+n); } //-------------------composition--------------------------- int ans=0; while(bt_h()) { ans+=findflow(st,999999999); } printf("%d\n",sum-ans); return 0; }
pain and happy in the cruel world.