主要学习的是zkw费用流。。
先用spfa在最短路上进行增广,直到无法增广为止,然后输出费用即可。。
模板:
bool spfa()
{
int i,now;
memset(vis,false,sizeof(vis));
for (i=0;i<=n;i++)//0是源点,n是汇点,根据实际情况更改即可。。
dis[i]=0x7fffffff;
head=0;
tail=1;
q[0]=n;
vis[n]=true;
dis[n]=0;
while (head<tail)
{
now=q[head];
head++;
vis[now]=false;
for (i=h[now];i;i=edge[i].next)
if (edge[i^1].v && dis[now]-edge[i].c<dis[edge[i].to])
{
dis[edge[i].to]=dis[now]-edge[i].c;
if (!vis[edge[i].to])
{
vis[edge[i].to]=true;
q[tail]=edge[i].to;
tail++;
}
}
}
return dis[0]!=0x7fffffff;
}
int dfs(int x,int f)
{
int w,used=0,i;
mark[x]=true;
if (x==n)
return f;
for (i=h[x];i;i=edge[i].next)
if (dis[edge[i].to]==dis[x]-edge[i].c && edge[i].v && !mark[edge[i].to])
{
w=f-used;
w=dfs(edge[i].to,min(w,edge[i].v));
sum+=w*edge[i].c;
edge[i].v-=w;
edge[i^1].v+=w;
used+=w;
if (used==f)
return f;
}
return used;
}
主程序调用:
while (spfa())
{
mark[n]=true;
while (mark[n])
{
memset(mark,false,sizeof(mark));
tmp+=dfs(0,0x7fffffff);
}
}