zoukankan      html  css  js  c++  java
  • HDU3367+并查集应用

    题意:找到一个这样的图,在这个图中,最多有一个环。

    使得所有的边的和最大。

    贪心+并查集

    首先把边排序,然后开始分类讨论。

    对于边ab(含有两个端点ab)

    如果a,b是属于两个不同的集合

          a b 是两个环中的点,则放弃ab

          a b 有一个是环,则把环当做另一个的祖先,之后在回溯祖先的时候,能找到该点是在某个环中。

     1 /*
     2 找到一个图,使得每一个连通分量最多有一个环
     3 */
     4 #include<stdio.h>
     5 #include<string.h>
     6 #include<stdlib.h>
     7 #include<algorithm>
     8 using namespace std;
     9 const int maxn = 10005;
    10 const int maxm = 100005;
    11 struct node{
    12     int u,v,val;
    13 }edge[ maxm ];
    14 int fa[ maxn ],circle[ maxn ];
    15 int find( int x ){
    16     if( fa[x]==x ) return x;
    17     fa[x] = find(fa[x]);
    18     return fa[x];
    19 }
    20 bool union_ab( int x,int y ){
    21     int fax = find(x);
    22     int fay = find(y);
    23     if( fax==fay ){
    24         if( circle[ fax ]==-1 ){
    25             circle[ fax ] = 1;
    26             return true;
    27         }//形成一个环
    28         return false;
    29         //已经是环
    30     }
    31     else{
    32         if( circle[ fax ]==circle[ fay ]&&circle[ fax ]==1 )
    33             return false;
    34         if( circle[ fax ]==1 )
    35             fa[ fay ] = fax;
    36         else
    37             fa[ fax ] = fay;
    38         //这里注意把环作为祖先,因为find
    39         return true;
    40     }
    41 }
    42 void init( int n ){
    43     for( int i=0;i<n;i++ ){
    44         fa[i] = i;
    45         circle[ i ] = -1;
    46     }
    47 }
    48 int cmp( node a,node b ){
    49     return a.val>b.val;
    50 }
    51 int main(){
    52     int n,m;
    53     while( scanf("%d%d",&n,&m)==2,n||m ){
    54         //if( n==0&&m==0 ) break;
    55         for( int i=0;i<m;i++ )
    56             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
    57         init( n );
    58         sort( edge,edge+m,cmp );
    59         int ans = 0;
    60         for( int i=0;i<m;i++ ){
    61             if( union_ab( edge[i].u,edge[i].v) )
    62                 ans += edge[i].val;
    63         }
    64         printf("%d
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code
    keep moving...
  • 相关阅读:
    设计模式之工厂方法3
    Orchard CMS中如何打包不带源码的模块
    Dump Checking
    认识WinDbg
    Bootstrap3.0学习第九轮(CSS补充)
    SVN版本冲突解决详解
    windbg Symbol file path
    SVN下错误集锦
    MvcMovieStore mvc5.0,EF6.01
    SQL Server中的窗口函数
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3176517.html
Copyright © 2011-2022 走看看