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...
  • 相关阅读:
    yocto/bitbake 学习资源
    QEMU/KVM学习资源
    ubuntu 中创建和删除用户
    git 重命名本地和远程分支
    Ubuntu 上搭建 FTP 服务器
    gdb 常见用法
    git log 显示与特定文件相关的 commit 信息
    基于 qemu system mode 运行 arm 程序
    基于 qemu user mode 运行 aarch64 程序
    checking in(airport)
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3176517.html
Copyright © 2011-2022 走看看