zoukankan      html  css  js  c++  java
  • POJ 2914 Minimum Cut【最小割】

    Description

    Given an undirected graph, in which two vertices can be connected by multiple edges, what is the size of the minimum cut of the graph? i.e. how many edges must be removed at least to disconnect the graph into two subgraphs?

    Input

    Input contains multiple test cases. Each test case starts with two integers N and M (2 ≤ N ≤ 500, 0 ≤ M ≤ N × (N − 1) ⁄ 2) in one line, where N is the number of vertices. Following are M lines, each line contains M integersAB and C (0 ≤ AB < NA ≠ BC > 0), meaning that there C edges connecting vertices A and B.

    Output

    There is only one line for each test case, which contains the size of the minimum cut of the graph. If the graph is disconnected, print 0.

    Sample Input

    3 3
    0 1 1
    1 2 1
    2 0 1
    4 3
    0 1 1
    1 2 1
    2 3 1
    8 14
    0 1 1
    0 2 1
    0 3 1
    1 2 1
    1 3 1
    2 3 1
    4 5 1
    4 6 1
    4 7 1
    5 6 1
    5 7 1
    6 7 1
    4 0 1
    7 3 1

    Sample Output

    2
    1
    2

    反思:最小割算法我很久没有想明白,智商很低吧...相信自己慢慢会理解的;
    一个值得看的资料链接:http://www.cnblogs.com/ylfdrib/archive/2010/08/17/1801784.html
    看着顺眼的代码:
    View Code
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    #define N 505
    #define inf 1000000000
    int n, m;
    int g[N][N];  //保存原图 
    int dist[N], node[N];  //dist[]保存一个积累量, node[]保存顶点 
    bool used[N];
    int mincut()
    {
        int i, j, k, pre, maxj, ans = inf;
        for(i = 0; i < n; i++)
            node[i] = i;    //保存顶点,固定顶点为0
        while(n > 1)
        {
            memset(used,0,sizeof(used));
            maxj = 1;
            used[node[0]] = 1;
            for(i = 1; i < n; i++)
            {
                dist[node[i]] = g[node[0]][node[i]]; //初始化距离数组dist[]
                if(dist[node[i]] > dist[node[maxj]])   //寻找最大距离——求最大生成树
                    maxj = i;
            }
            pre = 0;    //求最大生成树,并进行最小割操作。
            for(i = 1; i < n; i++)
            {
                if(i == n-1)
                {        //只剩最后一个没加入集合的点,更新最小割
                    ans = min(ans,dist[node[maxj]]);
                    for(k = 0; k < n; k++) //合并最后一个点以及推出它的集合中的点
                    g[node[k]][node[pre]] = g[node[pre]][node[k]] += g[node[k]][node[maxj]];
                    node[maxj] = node[--n];//缩点后的图
                }
                used[node[maxj]] = 1;
                pre = maxj;
                maxj = -1;
                for(j = 1; j < n; j++)
                    if(!used[node[j]])
                    {    //将上次求的maxj加入集合,合并与它相邻的边到割集
                        dist[node[j]] += g[node[pre]][node[j]];//dist[]保存的是一个积累量。
                        if(maxj == -1 || dist[node[maxj]] < dist[node[j]])
                            maxj = j;
                    }
            }
        }
         return ans;
    }
    int main()
    {
        while(scanf("%d %d",&n,&m) != -1)
        {
            memset(g,0,sizeof(g));
            while(m--)
            {
                int a, b, c;
                scanf("%d %d %d",&a,&b,&c);
                g[a][b] += c;
                g[b][a] += c;
            }
            printf("%d\n",mincut());
        }
     return 0;
    }
  • 相关阅读:
    表观遗传学|
    Mutation|DNM|
    Right journal|First-class paper|Mediocre paper|figure legend |Discussion|Introduction
    PCoA|NMDS|STRESS|RDA |RA|Unimodal|CCA|Generalized Joint Attribute Modeling
    缺失值|回归分析|协变关系|
    基金写作流程|留学回国人员启动资金
    nexage video asset tag
    获取的时候报cannot find package "golang.org /x/net/context",编译也报错误
    google play apk 下载
    vim golang 插件
  • 原文地址:https://www.cnblogs.com/Hilda/p/2662958.html
Copyright © 2011-2022 走看看