首页 > 代码库 > 图的全局最小割的Stoer-Wagner算法及例题

图的全局最小割的Stoer-Wagner算法及例题

Stoer-Wagner算法基本思想:如果能求出图中某两个顶点之间的最小割,更新答案后合并这两个顶点继续求最小割,到最后就得到答案。

算法步骤:

-------------------------------------------------------------------------------------------------------------------------

(1)首先初始化,设最小割ans = INF                                                                                                                       |

(2)任选一个顶点u加入集合S,定义W(S,p)为S中的所有点到S外一点p的权值总和                                                            |

(3)根据选定的u更新W(S,p)的值                                                                                                                            |

(4)选出W(S,p)中值最大的点作为新的S,若S=G(V),则继续步骤(3)                                                                          |

(5)最后进入S的两点s,t,用W(S,t)更新ans的值                                                                                                        |

(6)新建顶点c,边权w(c,v) = w(s,v)+w(t,v),删除顶点s,t及其相连的边                                                                         |

(7)若|V| > 1,则继续步骤(2)                                                                                                                            |

-------------------------------------------------------------------------------------------------------------------------

步骤(2)-(5)就是找出两个顶点,并求出它们的最小割W(S,t),步骤(6)是删除这两个顶点,重复操作,直至顶点数变为1

复杂度:O(n^3)

 

例题: POJ 2914 Minimum Cut

裸的最小割

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#define Mod 1000000007using namespace std;#define N 506int dis[N],node[N];int ans;int mp[N][N];int vis[N];int Sto_Wag(int n){    int maxi,pre,m;    int i,j;    for(i=1;i<=n;i++)        node[i] = i;    while(n > 1)    {        m = -1,maxi = 2;        for(i=2;i<=n;i++)        {            dis[node[i]] = mp[node[1]][node[i]];            vis[node[i]] = 0;            if(dis[node[i]] > m)            {                m = dis[node[i]];                maxi = i;            }        }        pre = 1;        vis[node[1]] = 1;        for(j=2;j<=n;j++)        {            vis[node[maxi]] = 1;            if(j == n)            {                ans = min(ans,m);                for(i=1;i<=n;i++)                {                    mp[node[pre]][node[i]] += mp[node[maxi]][node[i]];                    mp[node[i]][node[pre]] += mp[node[maxi]][node[i]];                }                node[maxi] = node[n--];            }            else            {                pre = maxi;                m = -1;                for(i=2;i<=n;i++)                {                    if(!vis[node[i]])                    {                        dis[node[i]] += mp[node[pre]][node[i]];                        if(dis[node[i]] > m)                        {                            m = dis[node[i]];                            maxi = i;                        }                    }                }            }        }    }    return 0;}int main(){    int n,m,u,v,w;    while(scanf("%d%d",&n,&m)!=EOF)    {        ans = Mod;        memset(mp,0,sizeof(mp));        while(m--)        {            scanf("%d%d%d",&u,&v,&w);            u++,v++;            mp[u][v] += w;            mp[v][u] += w;        }        Sto_Wag(n);        printf("%d\n",ans);    }    return 0;}
View Code