Topic Source: Hdu 3367 pseudoforest
Each connected block can have at most one ring to seek the largest forest
Thinking: Consider the largest spanning tree if the ancestors did not have the ring then merge if the ancestors are not the same if 2 trees do not have a ring merge if there are 1 trees with ring merge mark the tree has rings
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int MAXN = 100010; struct Edge {int u, V, W;}
E[MAXN];
int f[10010];
int VIS[MAXN];
int ok[10010];
int n, m;
BOOL CMP (Edge A, Edge b) {return A.W > B.W} int find (int x) {if (x!= f[x]) return f[x] = find (f[x));
return f[x];
int MST () {int sum = 0;
memset (Vis, 0, sizeof (VIS));
memset (OK, 0, sizeof (OK));
for (int i = 0; i < m, i++) {int x = find (E[I].U);
int y = find (E[I].V);
if (x!= y) {if (!ok[x] &&!ok[y]) {sum = E[I].W;
F[x] = y;
else if (!ok[x] | | |!ok[y]) {ok[x] = ok[y] = 1;
F[x] = y;
sum + + E[I].W;
} else if (!ok[x]) {ok[x] = 1;
sum + + E[I].W;
return sum;
int main () {while (scanf ("%d%d", &n, &m) && (n+m)) {for (int i = 0; i < n; i++) f[i] = i;
for (int i = 0; i < m i++) {scanf ("%d%d%d", &e[i].u, &E[I].V, &E[I].W);
}Sort (E, e+m, CMP);
printf ("%d\n", MST ());
return 0; }