您的位置:首页 > 其它

2016SDAU课程练习四1008 Problem H

2016-07-06 19:17 351 查看

Problem H

Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other)
Total Submission(s) : 81 Accepted Submission(s) : 41
[align=left]Problem Description[/align]
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.<br><br>

[align=left]Input[/align]
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.<br>The last test case is followed by a line containing two zeros, which means the
end of the input.<br>

[align=left]Output[/align]
Output the sum of the value of the edges of the maximum pesudoforest.<br&g
4000
t;

[align=left]Sample Input[/align]

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

[align=left]Sample Output[/align]

3
5

题意:

求一个图的最大连通子图,连通分量最多只可以形成一个环。在输入中给出顶点的个数、边的个数,要求编写一个程序实现所求边的权值最大。

解题思路:

采用并查集处理回路的问题,判断是否有环,并且考虑三种合并并查集的情况,和之前的问题一样。

#include<stdio.h>

 #include<string.h>

 #include<stdlib.h>

 #include<algorithm>

 using namespace std;

 const int maxn = 10005;

 const int maxm = 100005;

 struct node{

     int u,v,val;

 }edge[ maxm ];

 int fa[ maxn ],circle[ maxn ];

 int find( int x ){

     if( fa[x]==x ) return x;

     fa[x] = find(fa[x]);

     return fa[x];

 }

 bool union_ab( int x,int y ){

     int fax = find(x);

     int fay = find(y);

     if( fax==fay ){

         if( circle[ fax ]==-1 ){

             circle[ fax ] = 1;

             return true;

         }//形成一个环

         return false;

         //已经是环

     }

     else{

         if( circle[ fax ]==circle[ fay ]&&circle[ fax ]==1 )

             return false;

         if( circle[ fax ]==1 )

             fa[ fay ] = fax;

         else

             fa[ fax ] = fay;

         //这里注意把环作为祖先,因为find

         return true;

     }

 }

 void init( int n ){

     for( int i=0;i<n;i++ ){

         fa[i] = i;

         circle[ i ] = -1;

     }

 }

 int cmp( node a,node b ){

     return a.val>b.val;

 }

 int main(){

     int n,m;

     while( scanf("%d%d",&n,&m)==2,n||m ){

         //if( n==0&&m==0 ) break;

         for( int i=0;i<m;i++ )

             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);

         init( n );

         sort( edge,edge+m,cmp );

         int ans = 0;

         for( int i=0;i<m;i++ ){

             if( union_ab( edge[i].u,edge[i].v) )

                 ans += edge[i].val;

         }

         printf("%d\n",ans);

     }

     return 0;

 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: