线段树优化构图的费用流。
http://www.lydsy.com/JudgeOnline/problem.php?id=4276
/************************************************************** Problem: 4276 User: 1349367067 Language: C++ Result: Accepted Time:34393 ms Memory:17940 kb ****************************************************************/ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define MAXN 5010 #define inf 214748364 usingnamespacestd; intn; inta[MAXN],b[MAXN],c[MAXN]; intMin=inf,Max=-inf; intbia[MAXN*10],v[MAXN*200],pre[MAXN*200],flo[MAXN*200],cos[MAXN*200],num=0; intS=0,T=MAXN*10-3; voidinit() { scanf("%d",&n); for(inti=1;i<=n;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); b[i]--; if(a[i]<Min) Min=a[i]; if(b[i]>Max) Max=b[i]; } memset(bia,-1,sizeof(bia)); } voidadd_ed(intl,intr,intflow,intcost) { pre[num]=bia[l];bia[l]=num; flo[num]=flow;cos[num]=cost; v[num]=r; num++; pre[num]=bia[r];bia[r]=num; flo[num]=0;cos[num]=-cost; v[num]=l; num++; } voidbuild_tree(intn,intl,intr) { if(l==r) { add_ed(n,T,1,0); return; } intmid=(l+r)/2; add_ed(n,n*2,inf,0); add_ed(n,n*2+1,inf,0); build_tree(n*2,l,mid); build_tree(n*2+1,mid+1,r); return; } voidset_tree(intn,intl,intr,intL,intR,intk) { //cout<<n<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<k<<endl; //system("pause"); if(l==L&&r==R) { add_ed(k,n,inf,0); return; } intmid=(L+R)/2; if(r<=mid) {set_tree(n*2,l,r,L,mid,k);return;} if(l>mid) {set_tree(n*2+1,l,r,mid+1,R,k);return;} set_tree(n*2,l,mid,L,mid,k); set_tree(n*2+1,mid+1,r,mid+1,R,k); return; } boolvis[MAXN*10]; intans=0; //int from_[MAXN*200]={} boolE_K() { intsp[MAXN*20]={},flow[MAXN*10]={},cost[MAXN*10]={},from[MAXN*10]={}; intq,p,l,r; q=0;p=1; memset(cost,0xef,sizeof(cost)); sp[1]=S; memset(vis,false,sizeof(vis)); flow[S]=1;cost[S]=0;vis[S]=true; from[S]=-1; while(q<p) { l=sp[++q]; for(inti=bia[l];i!=-1;i=pre[i]) { r=v[i]; if(flo[i]&&cost[r]<cost[l]+cos[i]) { cost[r]=cost[l]+cos[i]; flow[r]=1; from[r]=i;//from_[i]=l; if(vis[r]==false) { vis[r]=true; sp[++p]=r; } } } vis[l]=false; } if(cost[T]<=0) returnfalse; ans+=cost[T]; //cout<<ans<<endl; for(inti=from[T];i!=-1;i=from[v[i^1]]) flo[i]--,flo[i^1]++; returntrue; } intmain() { init(); build_tree(1,Min,Max); for(inti=1;i<=n;i++) { //cout<<"********"<<endl; set_tree(1,a[i],b[i],Min,Max,40000+i); add_ed(S,40000+i,1,c[i]); } while(E_K()); printf("%d",ans); return0; }