zoukankan      html  css  js  c++  java
  • HDU1232——通畅工程(并查集)

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

    这道题是学习并查集的第一道题。

    并查集,他的思路是构成一个树结构,如果这两个节点的根节点相同,那么说明这两个节点在一个集合里,否则不再一个集合。

    查找根节点:当然是递归查找他上一层的父节点是什么。知道查找到的节点的父节点是他本身为止。

    int find(int x) {           
        return par[x] == x ? x : par[x] = find(par[x]);
    }

    将节点加入集合:为了方便查找,直接将节点连接到树的根节点上就可以了。

    void unite(int x,int y){
        x=find(x);
        y=find(y);
        if(x==y)return;
        par[x]=y;
       
    }

    下面说一下题意:

    这道题是希望所有点连通,那么就是希望所有点都在一个集合里。

    所以最多的起始路径数应该是n-1(即所有点都连接到根节点上),根据已知的已经连接的路,如果在一个集合那么就返回,不再一个集合就把他们放在一个集合里,然后路径数减一。

    #include<stdio.h>
    int par[1001];
    int ans;
    int k,n,m,a,b;
    int find(int x);
    void unio(int x,int y);
    int main(){
        while(~scanf("%d",&n)&&n!=0){
            scanf("%d",&m);
            for(int i=1;i<n+1;i++){
                par[i]=i;
            }
            k=n-1;
            for(int i=0;i<m;i++){
                scanf("%d%d",&a,&b);
               unio(a,b);
            }       
            printf("%d
    ",k);
        }
        return 0;
    }
    //两种查找根节点 
    int find(int x){
         while(par[x]!=x){
                x=par[x];
            }
            return x;
    } 
    //int find(int x)
    //{
    //    return par[x]==x?x:(par[x]=find(par[x]));
    //}
    //联结两个点 
    void unio(int x,int y){
        x=find(x);
        y=find(y);
        if(x==y)return;
        k--;
        par[x]=y;
       
    }
  • 相关阅读:
    page load时执行JavaScript
    解决Postgres无法连接的问题
    Linux环境设置IP及关闭防火墙
    解决VisualStudio无法调试的问题
    【PostgresSQL】同时更新两个表
    更改系统键盘
    【SQLSERVER】How to check current pool size
    BZOJ 1070: [SCOI2007]修车
    BZOJ 1069: [SCOI2007]最大土地面积
    BZOJ 1068: [SCOI2007]压缩
  • 原文地址:https://www.cnblogs.com/Yvettey-me/p/4541218.html
Copyright © 2011-2022 走看看