hdu 3367 最大伪森林(kruskal)

最大伪森林:原图的一个子图,在子图的各个连通分量中至多有一个环,且各边权和最大。

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

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 10000;
 8 const int M = 100000;
 9 int f[N];
10 bool cycle[N];
11 
12 struct Edge
13 {
14     int u, v, w;
15     bool operator < ( const Edge & o ) const
16     {
17         return w > o.w;
18     }
19 } edge[M];
20 
21 int findf( int x )
22 {
23     if ( f[x] != x ) f[x] = findf(f[x]);
24     return f[x];
25 }
26 
27 int main ()
28 {
29     int n, m;
30     while ( scanf("%d%d", &n, &m) != EOF )
31     {
32         if ( n == 0 && m == 0 ) break;
33         for ( int i = 0; i < m; i++ )
34         {
35             scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
36         }
37         for ( int i = 0; i < n; i++ )
38         {
39             f[i] = i;
40         }
41         sort( edge, edge + m );
42         memset( cycle, 0, sizeof(cycle) );
43         int sum = 0;
44         for ( int i = 0; i < m; i++ )
45         {
46             int u = edge[i].u, v = edge[i].v, w = edge[i].w;
47             u = findf(u), v = findf(v);
48             if ( u == v )
49             {
50                 if ( !cycle[u] )
51                 {
52                     sum += w;
53                     cycle[u] = 1;
54                 }
55             }
56             else
57             {
58                 if ( cycle[u] && cycle[v] )
59                 {
60                     continue;
61                 }
62                 sum += w;
63                 f[u] = v;
64                 if ( cycle[u] || cycle[v] )
65                 {
66                     cycle[v] = 1;
67                 }
68             }
69         }
70         printf("%d
", sum);
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4661564.html