Pseudoforest |
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) |
Total Submission(s): 157 Accepted Submission(s): 69 |
Problem Description
In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudoforests of G are the pseudoforest subgraphs of G that are not contained within any larger pseudoforest of G. A pesudoforest is larger than another if and only if the total value of the edges is greater than another one’s.
|
Input
The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges. The last test case is followed by a line containing two zeros, which means the end of the input.
|
Output
Output the sum of the value of the edges of the maximum pesudoforest.
|
Sample Input
3 3 0 1 1 1 2 1 2 0 1 4 5 0 1 1 1 2 1 2 3 1 3 0 1 0 2 2 0 0 |
Sample Output
3 5 |
Source
“光庭杯”第五届华中北区程序设计邀请赛 暨 WHU第八届程序设计竞赛
|
Recommend
lcy
|
分析:变形的最小生成树(Kruska算法),找到一个森林,使得每棵树都最多有一个环。在每棵树的根上再记录是否有环,以方便合并是判断。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int fa[10010], ok[10010]; int find(int x) { if (x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } typedef struct S { int u, v, w; } EDGE; EDGE edge[100010]; bool cmp(EDGE a, EDGE b) { return a.w > b.w; } int main() { int n, m, a, b, i, j, f1, f2, cnt, ans, k, t, T; while (scanf("%d%d", &n, &m) != EOF && n) { memset(ok, 0, sizeof (ok)); for (i = 0; i < n; ++i) fa[i] = i; cnt = 0; ans = 0; for (i = 0; i < m; ++i) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w); } sort(edge, edge + m, cmp); for (i = 0; i < m; ++i) { f1 = find(edge[i].u); f2 = find(edge[i].v); if (f1 == f2) { if (!ok[f1]) { ans += edge[i].w; ok[f1] = 1; } } else if (f1 != f2) { if (ok[f1] && ok[f2]) continue; else if (ok[f1] && !ok[f2]) { fa[f2] = f1; ans += edge[i].w; } else { fa[f1] = f2; ans += edge[i].w; } } } printf("%d\n", ans); } return 0; }