• 图的全局最小割的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 1000000007
    using namespace std;
    #define N 506
    
    int 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
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Day10 python基础---函数进阶
    Day9 python基础---函数初识
    Day8 python基础
    Day7 python基础
    Day6 python基础
    Day5 python基础
    Day4 python基础
    Day3 python基础
    TensorFlow学习笔记5-概率与信息论
    TensorFlow学习笔记6-数值计算基础
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3856367.html
Copyright © 2020-2023  润新知