BZOJ3876: [Ahoi2014]支线剧情
有下界最小费用可行流。建图可以优化,我没优化。
#include<algorithm> #include<cstdio> #include<cstring> using std::min; const int inf=1061109567; const int N=305; const int s=N-1; const int t=N-2; int n,z[N],q[N*N],c[N],d[N]; struct edge{ int v,w,f;edge*s; }e[N*N]; edge*a=e,*h[N]; void ins(int u,int v,int w,int f){ edge s={v,w,f,h[u]}; edge t={u,-w,0,h[v]}; *(h[u]=a++)=s; *(h[v]=a++)=t; } bool spfa(){ memset(c,63,sizeof c); memset(d,0,sizeof d); c[q[0]=t]=0; for(int a=0,b=0;a<=b;++a){ int u=q[a]; z[u]=0; for(edge*i=h[u];i;i=i->s) if(e[i-e^1].f&&c[u]-i->w<c[i->v]){ c[i->v]=c[u]-i->w; d[i->v]=d[u]+1; if(!z[i->v]++) q[++b]=i->v; } } return c[s]!=inf; } int dfs(int u,int v){ if(u==t)return v; int s=v; for(edge*i=h[u];i;i=i->s) if(c[i->v]==c[u]-i->w&&d[i->v]==d[u]-1&&i->f){ int j=dfs(i->v,min(i->f,s)); i->f-=j,s-=j; e[i-e^1].f+=j; if(!s)break; } if(s==v)c[u]=inf; return v-s; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ int j,v,w; scanf("%d",&j); ins(i,t,0,j); ins(i,1,0,inf); while(j--){ scanf("%d%d",&v,&w); ins(s,v,w,1); ins(i,v,w,inf); } } int k=0; while(spfa()) while(int j=dfs(s,inf)) k+=j*c[s]; printf("%d\n",k); }