1.初始化流量,计算出剩余图
2.根据剩余图计算层次图(BFS),若汇点不在层次图内,则算法结束
3.在层次图内用一次DFS增广
4.转步骤2
2.根据剩余图计算层次图(BFS),若汇点不在层次图内,则算法结束
3.在层次图内用一次DFS增广
4.转步骤2
层次图指用一次BFS计算每个节点到源点的距离(level),源点的level为0。Dinic精髓在第三步,在层次图内用一次DFS增广。在程序实现的时候,层次图并不需要被构造出来,只需要对每个顶点标记一个层次,寻找路径的时候,判断边是否满足level[u]+1==level[v]这一约束即可。
下面给出Dinic的伪码:
初始化,计算剩余图;
while(BFS()) //BFS过程的作用:1,计算层次图;2,当汇点不再层次图内时返回0
{
path.clear();
源点入栈path; //栈path保存层次图内从原点到终点的可行路径
while(源点的出度不为0)
{
u<-path.top;
if (u!=汇点) //在层次图内寻找一条从起点到终点的路径
{
if (u出度大于0)
将层次图内与u相连的点v入栈;
else
{
u出栈; //从path中删除
u的level=正无穷; //从层次图中删除
}
}
else //对路径增广
{
在剩余图中沿P增广;
令path.top为从起点可到达的最后一个顶点;
}
}
}
while(BFS()) //BFS过程的作用:1,计算层次图;2,当汇点不再层次图内时返回0
{
path.clear();
源点入栈path; //栈path保存层次图内从原点到终点的可行路径
while(源点的出度不为0)
{
u<-path.top;
if (u!=汇点) //在层次图内寻找一条从起点到终点的路径
{
if (u出度大于0)
将层次图内与u相连的点v入栈;
else
{
u出栈; //从path中删除
u的level=正无穷; //从层次图中删除
}
}
else //对路径增广
{
在剩余图中沿P增广;
令path.top为从起点可到达的最后一个顶点;
}
}
}
poj3281这题主要是构图的问题:把一头牛拆成两份,一份与对应Drink相连,一份与对应Food相连,两份相同牛之间连一条路径。再添加一个起点和一个终点,起点与每份Drink相连,每份Food与终点相连。所有路径的权值都为1,且方向一致指向从起点到终点。
poj3281的代码, Time:63MS