zoukankan      html  css  js  c++  java
  • 全局最小割(模板)

    #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;
    }
  • 相关阅读:
    保持URL不变和数字验证
    centOS ftp key?
    本地环境测试二级域名
    linux 解决You don't have permission to access 问题
    php smarty section loop
    php header Cannot modify header information headers already sent by ... 解决办法
    linux部分命令
    Linux 里面的文件操作权限说明
    用IT网络和安全专业人士视角来裁剪云的定义
    SQL Server 2008 R2炫酷报表"智"作有方
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4822998.html
Copyright © 2011-2022 走看看