bzoj3876: [Ahoi2014]支线剧情 费用流
Posted f321dd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3876: [Ahoi2014]支线剧情 费用流相关的知识,希望对你有一定的参考价值。
按照有下界网络流求可行流的方法求出最小费用可行流。
写的费用流多路增广,比裸ek快一点。
其实这题有很优越的建图方法,然而并不会。
#include<bits/stdc++.h> #define N 309 using namespace std; int cost,n; int d[N],s=N-1,t=N-2; bool p[N]; const int inf=1061109567; struct edge{ edge* s; int v,w,cp; }e[N*N],*back(e),*h[N]; void add( int u,int v,int w,int cp){ h[u]=&(*back++ =(edge){h[u],v,w,cp}); h[v]=&(*back++ =(edge){h[v],u,-w,0}); } bool spfa(){ static bool a[N]; queue<int> q; q.push(s); memset(d,63,sizeof d); d[s]=0; while(q.size()){ int u=q.front(); q.pop(); a[u]=0; for(edge* i=h[u];i;i=i->s) if(i->cp &&d[i->v]>d[u]+i->w){ d[i->v]=d[u]+i->w; if(!a[i->v]){ a[i->v]=1; q.push(i->v); } } } return d[t]!=inf; } int dfs(int u,int a){ int s=0; p[u]=1; for(edge* i=h[u];s!=a &&i;i=i->s){ if(!i->cp||p[i->v] ||d[i->v]!=d[u]+i->w) continue; int j=min(a-s,i->cp); if(i->v==t ||(j=dfs(i->v,j))){ s+=j; cost+=i->w*j; i->cp-=j; e[i-e^1].cp+=j; } } return s; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ int j,v,w; scanf("%d",&j); add(i,t,0,j); add(i,1,0,inf); while(j--){ scanf("%d%d",&v,&w); add(s,v,w,1); add(i,v,w,inf); } } while(spfa()){ memset(p,0,sizeof p); dfs(s,inf); } printf("%d\n",cost); }
以上是关于bzoj3876: [Ahoi2014]支线剧情 费用流的主要内容,如果未能解决你的问题,请参考以下文章