您的位置:首页 > 其它

hdu 3367 最大伪森林(kruskal)

2015-07-20 15:32 423 查看
最大伪森林:原图的一个子图,在子图的各个连通分量中至多有一个环,且各边权和最大。

方法:kruskal,只是排序按边权从大到小,合并的时候注意判断是否构成多个环。

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

const int N = 10000;
const int M = 100000;
int f
;
bool cycle
;

struct Edge
{
int u, v, w;
bool operator < ( const Edge & o ) const
{
return w > o.w;
}
} edge[M];

int findf( int x )
{
if ( f[x] != x ) f[x] = findf(f[x]);
return f[x];
}

int main ()
{
int n, m;
while ( scanf("%d%d", &n, &m) != EOF )
{
if ( n == 0 && m == 0 ) break;
for ( int i = 0; i < m; i++ )
{
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
}
for ( int i = 0; i < n; i++ )
{
f[i] = i;
}
sort( edge, edge + m );
memset( cycle, 0, sizeof(cycle) );
int sum = 0;
for ( int i = 0; i < m; i++ )
{
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
u = findf(u), v = findf(v);
if ( u == v )
{
if ( !cycle[u] )
{
sum += w;
cycle[u] = 1;
}
}
else
{
if ( cycle[u] && cycle[v] )
{
continue;
}
sum += w;
f[u] = v;
if ( cycle[u] || cycle[v] )
{
cycle[v] = 1;
}
}
}
printf("%d\n", sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: