zoukankan      html  css  js  c++  java
  • 并查集

    /*
    * 并查集
    * 解决动态连通性一类问题的一种算法
    * 在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,
    * 然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。
    * 这里使用并查集解决元素的集合归属的问题。
    * 我们让每一个集合成为一个组织,每个组织有一个头目,下面可以分成若干等级。
    * 如果两个元素向上找到的头目相同,那么他们就属于同一个组织。
    * 就是说每个元素只要知道自己的上级是谁,然后根据上级继续找到头目就能判断是不是属于一个组织。
    * 我们规定,当两个人满足同一组织规定的时候,两个人所在的组织也就是同一组织,可以合并起来。
    * 这个时候,只需要使得其中一个的组织头目臣服于另一个组织头目就可以了
    * 最好的情况下,每一个人都能一步找到头目,这样查找两个人的组织关系的效率是很高的
    * 在查找的时候,顺便将查找路径上的人的上级直接定义为组织头目,来压缩路径是很好的办法
    * 这里在图的连通的应用中很有价值,比如krustal算法判断点的连通性。
    * */
    public class _Union_Set_Implement {
        private int size;
        
        //father[i]==i的时候说明 i就是这个组织的头目
        private int[] father;
        private int OriginationNum;
    
        public _Union_Set_Implement(int size) {
            this.size = size;
            this.OriginationNum = size;
            this.father = new int[this.size];
    
            for (int i = 0; i < this.size; this.father[i] = i++);
    
        }
    
        private int findOrigination(int v) {
            int t;
            for (t = v; this.father[t] != t; t = this.father[t]);
    
            while (this.father[v] != t) {
                int tt = this.father[v];
                this.father[v] = t;
                v = tt;
            }
    
            return t;
        }
    
        public void Merge(int x, int y) {
            int fx = this.findOrigination(x);
            int fy = this.findOrigination(y);
            if (fx != fy) {
                --this.OriginationNum;
                this.father[fx] = fy;
            }
        }
        public boolean isSameOrigination(int x,int y){
            return findOrigination(x)==findOrigination(y);
        }
        public int getOriginationNum() {
            return this.OriginationNum;
        }
    }

    这里利用并查集来解决一个问题

    /*
    * 题目详情
    * 在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。
    * 最后要解决的是整幅图的连通性问题。
    * 比如随意给你两个点,让你判断它们是否连通,
    * 或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路
    * 4 2
    * 1 3
    * 4 3
    * */
    
    public class _UnionSet {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            _Union_Set_Implement union=new _Union_Set_Implement(scanner.nextInt());
            int routenum=scanner.nextInt();
            for (int i = 0; i < routenum; i++) {
                int a=scanner.nextInt()-1;
                int b=scanner.nextInt()-1;
                union.Merge(a,b);
            }
            System.out.printf("还需要修建%d条路",union.getOriginationNum()-1);
        }
    }
  • 相关阅读:
    SDN第三次上机作业
    团队作业——Beta冲刺
    SDN第二次上机作业
    在mpvue中使用map如何避坑
    仿一个好玩的滑动效果
    乡音
    mpvue支持小程序的分包加载
    台风🌀和口腔溃疡
    记一次cocos项目的加载速度优化
    如何用ajax下载文件
  • 原文地址:https://www.cnblogs.com/Coder-Pig/p/6758498.html
Copyright © 2011-2022 走看看