码迷,mamicode.com
首页 > 其他好文 > 详细

全局最小割

时间:2017-12-19 21:08:13      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:turn   max   set   div   全局   cut   ==   mem   oid   

stoer-Wagner算法

进行n轮操作,每轮操作确定一对点s,t被割开情况下的最小割,然后将s,t合并。s,t为操作中最后剩下的两个点。

操作类似prim求最大生成树,每次将与当前集合相邻的距离最大的点合并到集合中,最后剩下s,t两点。

代码来自wiki,可以堆优化

const int maxn = 550;
const int inf = 1000000000;
int n, r;
int edge[maxn][maxn], dist[maxn];
bool vis[maxn], bin[maxn];
void init() {
    memset(edge, 0, sizeof(edge));
    memset(bin, false, sizeof(bin));
}
int contract( int &s, int &t ) {        // Find s,t
    memset(dist, 0, sizeof(dist));
    memset(vis, false, sizeof(vis));
    int i, j, k, mincut, maxc;
    for(i = 1; i <= n; i++) {
        k = -1;
        maxc = -1;
        for(j = 1; j <= n; j++)if(!bin[j] && !vis[j] && dist[j] > maxc) {
                k = j;
                maxc = dist[j];
            }
        if(k == -1)return mincut;
        s = t;
        t = k;
        mincut = maxc;
        vis[k] = true;
        for(j = 1; j <= n; j++)if(!bin[j] && !vis[j])
                dist[j] += edge[k][j];
    }
    return mincut;
}

int Stoer_Wagner() {
    int mincut, i, j, s, t, ans;
    for(mincut = inf, i = 1; i < n; i++) {
        ans = contract( s, t );
        bin[t] = true;
        if(mincut > ans)mincut = ans;
        if(mincut == 0)return 0;
        for(j = 1; j <= n; j++)if(!bin[j])
                edge[s][j] = (edge[j][s] += edge[j][t]);
    }
    return mincut;
}

 

全局最小割

标签:turn   max   set   div   全局   cut   ==   mem   oid   

原文地址:http://www.cnblogs.com/zhujiangning/p/8067609.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!