线段树优化构图的费用流。

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;

}
View Code