首页 > 其他分享 >并查集

并查集

时间:2023-04-25 18:11:26浏览次数:31  
标签:findHead aHead parentMap sizeMap 查集 put public

并查集

并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素

合并(Union):合并两个元素所属集合(合并对应的树)
查询(Find):查询某个元素所属集合(查询对应的树的根节点),这可以用于判断两个元素是否属于同一集合


import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class UnionSet<V> {

    Map<V, V> parentMap;
    Map<V, Integer> sizeMap;

    public UnionSet(List<V> list) {
        parentMap = new HashMap<>(list.size());
        sizeMap = new HashMap<>(list.size());
        for (V v : list) {
            parentMap.put(v, v);
            sizeMap.put(v, 1);
        }
    }

    public V findHead(V v) {
        Stack<V> stack = new Stack<>();
        while (v != parentMap.get(v)) {
            stack.push(v);
            v = parentMap.get(v);
        }
        while (!stack.isEmpty()) {
            parentMap.put(stack.pop(), v);
        }
        return v;
    }

    public void union(V a, V b) {
        V aHead = findHead(a);
        V bHead = findHead(b);
        if (aHead != bHead) {
            int aSize = sizeMap.get(aHead);
            int bSize = sizeMap.get(bHead);
            V larger = aSize >= bSize ? aHead : bHead;
            V smaller = larger == aHead ? bHead : aHead;
            parentMap.put(smaller, larger);
            sizeMap.put(larger, aSize + bSize);
            sizeMap.remove(smaller);
        }
    }

    public boolean isSameSet(V a, V b) {
        return findHead(a) == findHead(b);
    }
    
    public int sets() {
        return sizeMap.size();
    }
}

标签:findHead,aHead,parentMap,sizeMap,查集,put,public
From: https://www.cnblogs.com/annamaple/p/17353449.html

相关文章

  • hdu 5441 长春区域赛网络赛 1005 Travel(并查集)
    题目链接:hdu5441题目大意:有一个n个点的无向图,给出m条边的边权,给出q次询问,每次给出一个值,求用到所有边权不大于这个值的边的情况下,能够互相到达的点对的个数(自己到自己不算)题目分析:首先我们对于边按照边权从小到大排序,对于询问按照值从小到大排序。枚举每次询问,从前到后扫描边,如果......
  • 并查集及其扩展(附例题与完整讲解cpp)
    文章目录基础并查集1.P1551亲戚2.P1536村村通种类并查集1.P1892[BOI2003]团伙2.P1525[NOIP2010提高组]关押罪犯3.P2024[NOI2001]食物链带权并查集基础并查集并查集就是用来维护一些元素之间的关系的集合。例如A的亲戚是B,则我们可以把A与B放到同一个集合中,表示AB属......
  • 23-4-15--并查集--部落
    在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。输入格式:输入在第一行给出一个正整数N(≤104),是已知小圈子的个数......
  • 算法-并查集-200
    publicclassSolution{publicintNumIslands(char[][]grid){if(grid==null||grid.Count()==0)return0;introwCount=grid.Count();intcolCount=grid[0].Count();intwaters=0;UnionFinduf=newUnionFind(grid);for......
  • AGC002D Stamp Rally 多种做法 kruskal重构树/可持久化并查集/整体二分
    D-StampRally(atcoder.jp)这题做法很多,我写的是可持久化并查集做法,但是裸的可持久化并查集是$O(nlog^3n)$,能过但是很慢!看洛谷的题解有一位大佬写了一个很妙的并查集的写法,按秩合并,每一步合并时用vector记录一下这个被合并到的节点的size和当前的时间,这样做可以找到每一个时......
  • HDU 1878 欧拉回路 (并查集+欧拉回路)
    题目地址:HDU1878这个题要注意欧拉回路与欧拉通路的区别。在都保证连通性的前提下,欧拉回路要求每个点的度数都是偶数,而欧拉通路允许两个点的度数是奇数。所以这题用并查集判断连通性后判断下度数就可以了。代码如下:#include<iostream>#include<string.h>#include<math.h>#in......
  • POJ 2337 Catenyms (欧拉回路+并查集)
    题目地址:POJ2337这题跟POJ1386差不多,只不过这题多一个输出路径而已。按字母来建边,每个单词的首字母和尾字母加边。先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个。就可以形成欧拉路径代码如下:#include<iostream......
  • POJ 1182 食物链(种类并查集)
    题目地址:POJ1182一道很经典的种类并查集的题目。利用互相之间的关系来进行权值的维护。代码如下:#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<stdlib.h>#include<math.h>#include<ctype.h>#include<queue>#in......
  • POJ 1703 Find them, Catch them(种类并查集)
    题目地址:POJ1703种类并查集水题。代码如下:#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<stdlib.h>#include<math.h>#include<ctype.h>#include<queue>#include<map>#includ......
  • POJ 1988 Cube Stacking (种类并查集)
    题目地址:POJ1988   这道题的查找合并的方法都能想的到,就是一点没想到,我一直天真的以为查询的时候,输入后能马上输出,这样的话在合并的时候就要所有的结点值都要算出来,但是经过路径压缩之后,没办法全部都处理到,如果不压缩妥妥的TLE。。于是看了看网上的题解。才发现自己是多......