• 全局最小割(模板)


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define MAX_N 500 + 16
    #define INF 0x3f3f3f3f
    int G[MAX_N][MAX_N];
    int v[MAX_N];    // v[i]代表节点i合并到的顶点
    int w[MAX_N];    // 定义w(A,x) = ∑w(v[i],x),v[i]∈A
    bool visited[MAX_N];    // 用来标记是否该点加入了A集合
    int stoer_wagner(int n)
    {
        int min_cut = INF;
        for (int i = 0; i < n; ++i){
            v[i] = i;    // 初始还未合并,都代表节点本身
        }
        while (n > 1)
        {
            int pre = 0;    // pre用来表示之前加入A集合的点(在t之前一个加进去的点)
            memset(visited, 0, sizeof(visited));
            memset(w, 0, sizeof(w));
            for (int i = 1; i < n; ++i){
                int k = -1;
                for (int j = 1; j < n; ++j)  // 选取V-A中的w(A,x)最大的点x加入集合
                {
                    if (!visited[v[j]])
                    {
                        w[v[j]] += G[v[pre]][v[j]];
                        if (k == -1 || w[v[k]] < w[v[j]]){
                            k = j;
                        }
                    }
                }
                visited[v[k]] = true;    // 标记该点x已经加入A集合
                if (i == n - 1)    // 若|A|=|V|(所有点都加入了A),结束
                {
                    const int s = v[pre], t = v[k];    // 令倒数第二个加入A的点(v[pre])为s,最后一个加入A的点(v[k])为t
                    min_cut = min(min_cut, w[t]);    // 则s-t最小割为w(A,t),用其更新min_cut
                    for (int j = 0; j < n; ++j)    // Contract(s, t)
                    {
                        G[s][v[j]] += G[v[j]][t];
                        G[v[j]][s] += G[v[j]][t];
                    }
                    v[k] = v[--n];    // 删除最后一个点(即删除t,也即将t合并到s)
                }
    // else 继续
                pre = k;
            }
        }
        return min_cut;
    }
    int main(int argc, char *argv[]){
        int n, m;
        while (scanf("%d%d", &n, &m) != EOF){
            memset(G, 0, sizeof(G));
            while (m--){
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                G[u][v] += w;
                G[v][u] += w;
            }
            printf("%d
    ", stoer_wagner(n));
        }
        return 0;
    }
  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4822998.html
Copyright © 2020-2023  润新知