bool makelevel() { memset(level,-1,sizeof(level)); q[1]=0; level[0]=0; head=1,tail=1; for(int head=1;head<=tail;head++) { for(int i=lin[q[head]];i;i=e[i].next) { if(level[e[i].y]<0&&e[i].v>0) { level[e[i].y]=level[q[head]]+1; q[++tail]=e[i].y; } } } return level[n+m+1]>=0; } int MAXflow(int aa,int flow) { if(aa==n+m+1)return flow; int maxflow=0,d=0; for(int i=lin[aa];i&&maxflow<flow;i=e[i].next) { if(e[i].v&&level[e[i].y]==level[aa]+1) { if(d=MAXflow(e[i].y,min(flow-maxflow,e[i].v))) { e[i].v-=d; e[e[i].h].v+=d; maxflow+=d; } } } if(maxflow<=0) level[aa]=-1; return maxflow; } void dinic() { int d; while(makelevel()) while(d=MAXflow(0,99999999)) ans+=d; }
费用流模板
bool spfa() { memset(vis,0,sizeof(vis)); memset(dis,12,sizeof(dis)); dis[1]=0; vis[1]=true; q[0]=1; int head=0,tail=0; while (head<=tail) //队列不为空 { int tn=q[head++]; for (int te=link[tn];te;te=edge[te].next) //枚举边 { int ty=edge[te].y; if (edge[te].flow &&(dis[tn]+edge[te].v<dis[ty])) //首先的有流量再判断费用 { if (!vis[ty]) //不在队列里。 { q[++tail]=ty; vis[ty]=true; } dis[ty]=dis[tn]+edge[te].v; lastnode[ty]=tn; lastedge[ty]=te; //增广路的记录,用于下面的增广。 } } vis[tn]=false; } return(dis[t]!=oo); //如果到t的最短距离存在,表明存在一个费用最小的增广路。 } void agu() //按照增广路径进行流量增减 { int delta=oo; for (int now=t;now!=s;now=lastnode[now]) if (edge[lastedge[now]].flow<delta ) //找出流量 delta=edge[lastedge[now]].flow; for (int now=t;now!=s;now=lastnode[now]) //更新流量 { int te=lastedge[now]; edge[te].flow-=delta; int re=edge[te].reverse; edge[re].flow+=delta; ans+=delta*(-edge[te].v); } } void costflow() { while (spfa()) agu(); cout<<ans<<endl; }