HDU 3002 King of Destruction(SW求最小割的值)

还是一道很典型的求最小割的值,算法依旧。

这次做这道题,我模拟了一下算法实行,发现这个模板在对点删除的处理上很巧妙。通过这次研究,算法大致的步骤和实现方法,我已经知道是怎么样的流程,但是具体的证明之类的还是很迷糊。

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 110;
const int INF = 0x3fffffff;
int n, m;
int g[N][N], v[N], d[N];

int Stoer_wagner() 
{
    bool vis[N];
    int i, j, res = INF;
    for ( i = 0; i < n; ++i ) v[i] = i;
    while ( n > 1 ) {
        int maxp = 1, prev = 0;
        for ( i = 1; i < n; ++i ) {
            d[v[i]] = g[v[0]][v[i]];
            if ( d[v[i]] > d[v[maxp]] ) maxp = i;
        }
        memset( vis, 0, sizeof(vis) );
        vis[v[0]] = true;
        for ( i = 1; i < n; i++ ) {
            if ( i == n-1 ) {
                res = min( res, d[v[maxp]] );
                for ( j = 0; j < n; ++j ) {
                    g[v[prev]][v[j]] += g[v[j]][v[maxp]];
                    g[v[j]][v[prev]] = g[v[prev]][v[j]];
                }
                v[maxp] = v[--n];
            }
            vis[v[maxp]] = true;
            prev = maxp;
            maxp = -1;
            for ( j = 1; j < n; ++j ) 
                if ( !vis[v[j]] ) {
                    d[v[j]] += g[v[prev]][v[j]];
                    if ( maxp == -1 || d[v[maxp]] < d[v[j]] ) maxp = j;
                }
        }
    }
    return res;
}
            
int main()
{
    while ( scanf("%d%d", &n, &m ) == 2 ) {
        memset( g, 0, sizeof(g) );
        int x, y, z;
        while ( m-- ) {
            scanf("%d%d%d", &x, &y, &z);
            g[x][y] += z;
            g[y][x] += z;
        }
        printf("%d\n", Stoer_wagner());
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值