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

来源:互联网 发布:帝国cms 首页调用内容 编辑:程序博客网 时间:2024/05/29 11:45

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

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

代码如下:

#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());    }}