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;
    }
  • 相关阅读:
    Invalid bound statement (not found)解决方法
    MySQL的sum()函数
    关于Mybatis的java.lang.UnsupportedOperationException异常处理
    博客迁移
    Building Blog(个性化博客)2
    走一波服务器
    JZ高中OJ 1036. [SCOI2009]迷路
    JZ初中OJ 2296. [noip普及组2]神殿
    JZ初中OJ 2295. [noip普及组2]栈
    JZ初中OJ 2298. [noip普及组2]异或
  • 原文地址:https://www.cnblogs.com/Hilda/p/2662958.html
Copyright © 2011-2022 走看看