您的位置:首页 > 理论基础 > 计算机网络

soj 3134: windy和水星 Stoer-Wagner算法求无向图的最小割集:一个无向连通网络,去掉一个边集可以使其变成两个连通分量则这个边集就是割集;最小割集当然就权和最小的割集

2011-09-20 18:03 639 查看

Description

windy被请到了水星交通部,交通部长现在想知道水星的交通安全度为多少在水星上有n座城市,任意两座城市之间有一条权值在[1,10^5]的双向路定义:为了使得这n座城市至少有两座之间不连通,最少需要破坏的权值为安全度求水星的交通安全度

Input

输入包含多组测试数据,每组数据第一行有一个整数,n ( 2 <= n <= 100 )接下来n行,每行n个整数,除主对角线外,均为范围在[1,10^5]的整数,对角线上的权值保证为0,保证[i][j]=[j][i]

Output

每组数据输出一行,为水星的交通安全度

Sample Input

30 1 31 0 23 2 0

Sample Output

3

//

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

const int MAXN = 501;

const int MAXV = 0x3F3F3F3F;

int n,m,v[MAXN],mat[MAXN][MAXN],dis[MAXN];

bool vis[MAXN];

int res;

int Stoer_Wagner(int n) {

int res = MAXV;

for (int i = 0;i < n;i++)

v[i] = i;

while (n > 1) {

int maxp = 1,prev = 0;

for (int i = 1;i < n;i++) {//初始化到已圈集合的割大小

dis[v[i]] = mat[v[0]][v[i]];

if (dis[v[i]] > dis[v[maxp]])

maxp = i;

}

memset(vis,0,sizeof(vis));

vis[v[0]] = true;

for (int i = 1;i < n;i++) {

if (i == n - 1) { //只剩最后一个没加入集合的点,更新最小割

res = min(res,dis[v[maxp]]);

for (int j = 0; j < n; j++) { //合并最后一个点以及推出它的集合中的点

mat[v[prev]][v[j]] += mat[v[j]][v[maxp]];

mat[v[j]][v[prev]] = mat[v[prev]][v[j]];

}

v[maxp] = v[--n];//缩点后的图

}

vis[v[maxp]] = true;

prev = maxp;

maxp = -1;

for (int j = 1;j < n;j++)

if (!vis[v[j]]) { //将上次求的maxp加入集合,合并与它相邻的边到割集

dis[v[j]] += mat[v[prev]][v[j]];

if (maxp == -1 || dis[v[maxp]] < dis[v[j]])

maxp = j;

}

}

}

return res;

}

int main()

{

while (scanf("%d", &n) != EOF)

{

memset(mat,0,sizeof (mat));

int x,y,z;

int i,j;

for(i=0;i<n;i++)

{

for(j=0;j<n;j++)

{

scanf("%d",&mat[i][j]);

}

}

printf("%d\n",Stoer_Wagner(n));

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐