Pseudoforest(伪最大生成树)
Pseudoforest |
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) |
Total Submission(s): 389 Accepted Submission(s): 165 |
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
|
/* 初级想方法,最大生成树再加一条最长边 讲解:没看明白题意的傻逼想法,题目说不是最大生成树,森林也可以,但是最多只能有一个环 正解:将所有的边都加到树上,加的时候如果两点在同一个并查集:如果原来有环就不能加 如果不在同一个并查集:如果原来两个都有环不能加 */ #include<bits/stdc++.h> using namespace std; struct node { int u,v,val; node() {} node(int a,int b,int c) { u=a; v=b; val=c; } bool operator < (const node &a) const { return val>a.val; } }; vector<node>edge; int bin[10005]; int n,m; int x,y,val; int h[10005];//表示当前集合有没有环 long long cur=0; void init() { for(int i=0;i<=n;i++) { bin[i]=i; h[i]=0; } edge.clear(); cur=0; } int findx(int x) { int temp=x; while(x!=bin[x]) x=bin[x]; bin[temp]=x; return x; } int main() { //freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF&&(n||m)) { init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&val); edge.push_back(node(x,y,val)); } sort(edge.begin(),edge.end()); for(int i=0;i<edge.size();i++) { int fx=findx(edge[i].u); int fy=findx(edge[i].v); if(fx==fy)//两个原来就是一个并查集的就可能产生环了 { if(h[fx])//有环了 continue; cur+=edge[i].val; h[fx]=1; } else { if(h[fx]&&h[fy])//两个集合都有环不可以 continue; bin[fy]=fx; cur+=edge[i].val; if(h[fx]||h[fy]) h[fx]=1; } } printf("%lld\n",cur); } return 0; }
我每天都在努力,只是想证明我是认真的活着.