Problem H

Time Limit : 10000/5000ms (Java/Other)   Memory Limit :65536/65536K (Java/Other)

Total Submission(s) : 1   Accepted Submission(s) : 1

Problem Description

In graph theory, apseudoforest is an undirected graph in which every connected component has atmost one cycle. The maximal pseudoforests of G are the pseudoforest subgraphsof G that are not contained within any larger pseudoforest of G. A pesudoforestis larger than another if and only if the total value of the edges is greaterthan another one’s.<br><br>

Input

The input consists of multipletest 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 vertexesand the number of the edges. The next m lines, each line consists of threeintegers, 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 multipleedges.<br>The last test case is followed by a line containing two zeros,which means the end of the input.<br>

Output

Output the sum of the value ofthe edges of the maximum pesudoforest.<br>

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

kruskal变形：

1.     从大到小排序

2.     合并时，如果会生成两个环，则不合并，需要数组标记。

1）如果是两棵树在进行合并操作

2）如果是是同一颗树在进行合并操作。

`#include<bits/stdc++.h>using namespace std;int fa;bool vis;struct node{    int x,y,v;}a;int find(int x){    return x==fa[x]?x:fa[x]=find(fa[x]);}int cmp(node b,node c)//这里要从大到小排序{    return b.v>c.v;}int main(){    int n,m;   while( scanf("%d%d",&n,&m)!=EOF&&(n||m))   {       int num=0;    for(int i=0;i<=n;i++)        fa[i]=i;        memset(vis,0,sizeof(vis));     for(int i=1;i<=m;i++)         {            int x,y,v;            scanf("%d%d%d",&x,&y,&v);            a[num].x=x;            a[num].y=y;            a[num].v=v;            num++;           }        sort(a,a+num,cmp);        int ans=0;        for(int i=0;i<num;i++)        {            int r1=find(a[i].x);            int r2=find(a[i].y);            if(r1!=r2)//表示两棵树            {            if(vis[r1]==1&&vis[r2]==1)//如果两棵树都有环，则不能合并                    continue;            if(vis[r1]||vis[r2])//如果其中有一个有环，合并            {                vis[r1]=vis[r2]=1;//标记有环            }                fa[r1]=r2;                ans+=a[i].v;            }            else if(!vis[r1])//如果在一棵树内，且没有环            {                //不能进行合并操作，不然会产生环，加上权值即可                ans+=a[i].v;                vis[r1]=1;            }        }        printf("%d\n",ans);   }   return 0;}`