Dinic算法 (poj3281 Dining)

关于Dinic算法(Dinic's algorithm, Dinitz blocking flow algorithm)步骤: 
  1.初始化流量,计算出剩余图
  
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为从起点可到达的最后一个顶点;
        }
     }
  }

poj3281这题主要是构图的问题:把一头牛拆成两份,一份与对应Drink相连,一份与对应Food相连,两份相同牛之间连一条路径。再添加一个起点和一个终点,起点与每份Drink相连,每份Food与终点相连。所有路径的权值都为1,且方向一致指向从起点到终点。

poj3281的代码, Time:63MS
Code


Dinic参考: http://en.wikipedia.org/wiki/Dinitz_blocking_flow_algorithm
     王欣上《浅谈基于分层思想的网络流算法》
     MH.Alsuwaiyel《算法设计技巧与分析》(Algorithms Design Techniques and Analysis)
posted @ 2009-07-17 19:05  MyShowTime  阅读(2757)  评论(0编辑  收藏  举报