zoukankan      html  css  js  c++  java
  • hdu 3367 伪森林(kruskal)

    http://acm.hdu.edu.cn/showproblem.php?pid=3367

    求pseudoforest伪森林,要求每个连通分量最多可以有一个环。求能构成的最大值

    我是用kruskal的方法按照求最大生成树那样求的,只不过要加一个判断,就是判断两颗子树是够成环,如果各成环,就不能合并,如果只有其中一个成环或者都不成环,那么就可以合并,并对其进行标记。。。

    View Code
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 const int N=10010;
     6 using namespace std;
     7 
     8 int n,m;
     9 int parent[N];
    10 int visited[N];//用来标记是否存在环
    11 
    12 struct Edge {
    13     int u,v,w;
    14     bool operator < (const Edge &p) const {
    15         return p.w<w;//从大到小
    16     }
    17 }edge[N*10];
    18 
    19 
    20 //初始化
    21 void UFset(){
    22     for(int i=0;i<n;i++)
    23         parent[i]=-1;
    24 }
    25 
    26 int Find(int x){
    27     int s;
    28     for(s=x;parent[s]>=0;s=parent[s]);
    29     //路径压缩,优化
    30     while(s!=x){
    31         int temp=parent[x];
    32         parent[x]=s;
    33         x=temp;
    34     }
    35     return s;
    36 }
    37 
    38 //合并
    39 void Union(int R1,int R2){
    40     int r1=Find(R1);
    41     int r2=Find(R2);
    42     int temp=parent[r1]+parent[r2];
    43     if(parent[r1]>parent[r2]){
    44         parent[r1]=r2;
    45         parent[r2]=temp;
    46     }else {
    47         parent[r2]=r1;
    48         parent[r1]=temp;
    49     }
    50 }
    51 
    52 
    53 int main(){
    54     while(scanf("%d%d",&n,&m)!=EOF){
    55         if(n==0&&m==0)break;
    56         memset(visited,0,sizeof(visited));
    57         int u,v,ans=0;
    58         for(int i=0;i<m;i++){
    59             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
    60         }
    61         sort(edge,edge+m);
    62         UFset();
    63         for(int i=0;i<m;i++){
    64             u=Find(edge[i].u);
    65             v=Find(edge[i].v);
    66             if(u!=v){
    67                 if(visited[u]&&visited[v])continue;  //都存在环
    68                 if(visited[u]||visited[v])
    69                     visited[u]=visited[v]=1;
    70                 ans+=edge[i].w;
    71                 Union(u,v);
    72             }else if(!visited[u]||!visited[v]){
    73                 Union(u,v);
    74                 visited[u]=visited[v]=1;
    75                 ans+=edge[i].w;
    76             }
    77         }
    78         printf("%d\n",ans);
    79     }
    80     return 0;
    81 }
    82 
    83                 
  • 相关阅读:
    day14_oracle数据库备份
    day13_存储过程小记
    day13_先沃联盟定时任务
    day13_自动抽取数据——监控存储过程
    [笔记]《HTTP权威指南》- 实体和编码
    [笔记]《白帽子讲Web安全》- Web框架安全
    [笔记]《Vue移动开发实战技巧》- Vue-router使用
    WPF与Win32互操作
    [翻译]HTML5
    学习资料收藏
  • 原文地址:https://www.cnblogs.com/wally/p/2891138.html
Copyright © 2011-2022 走看看