预流推进

来源:互联网 发布:怎样开通淘宝 编辑:程序博客网 时间:2024/05/03 01:19








预流推进算法



预流推进算法(压入与重标记方法):

预流推进算法将网络从源点到汇点至于从上到下的高度中。在算法执行过程中,每个节点的存留量(入流-出流)>=0,当一个点的存留量大于零时,则称此结点为活结点。算法从源点开始向下推流,通过不断地寻找活结点,将流量推向以该点为起点的可推流边(可推流边指与该点相连且高度比该点小1的边),该过程即为压入。如果在该点处找不到可推流边,则将该点的高度加1,以实现将过大的流向后推进,该过程称为重标记。因此,在预流推进算法的一次迭代中,要么执行压入操作,要么执行重标记操作。

综上,预流推进算法的框架:

1)、构造初始流。将源点高度标记为n,其余点高度均为0;

2)、如果残留网络中不存在活结点,则算法结束。否则继续执行下一步;

3)、选取活结点,如果该结点出边为可推流边,则沿此边推流,否则将该节点高度加1,执行步骤2)。

g[][]为每边的容量,c[]为每个点的存留量,h[]为每个顶点的高度,sum为最大流。

则预流推进算法代码如下:

void maxflow(int s,int e)

{

         memset(c,0,sizeof(c));

         c[s]=MAXINT;

         c[e]=-MAXINT;

         memset(h,0,sizeof(h));

         h[s]=n;

         sum=0;

        

         queue<int> que;                 //活顶点队列

         que.push(s);

    while(!que.empty())

         {

                   int u=que.front();

                   que.pop();

                  

                   for (int i=0;i<n;i++)

                            if (u==s||h[u]==h[i]+1)

                            {

                                     push(u,i,e);

                                     if (i!=s&&i!=e) que.push(i);

                            }

                   if (u!=s&&u!=e&&c[u]>0)

                   {

            relabel(u);

            que.push(u);

        }

         }

}

void push(int u,int v,int e)

{

         int min=c[u]<g[u][v]? c[u] : g[u][v];

         if (v==e) sum+=min;

         g[u][v]-=min;

         g[v][u]=+min;

         c[u]-=min;

         c[v]+=min;

}

void relabel(int u)

{

         h[u]++;

}


http://hi.baidu.com/hins_pan/item/e9e4e1da57b601ec54347f28

0 0
原创粉丝点击