网络流dinic模板
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;
}

浙公网安备 33010602011771号