首页 > TAG信息列表 > 查集
CSP-S2019 树上的数(并查集,dfs)
CSP-S2019 树上的数 \(n\) 树。\(n\) 排列卡片。\(i\) 卡片初始在 \(p_i\)。每次删一条边可以交换两端卡片。删光边最后卡片 \(i\) 位置 \(P_i\)。求字典序最小 \(P\)。 CODE 无可奉告。并查集
声明:与学校集训内容无关。 并查集是一种树形结构,基本的应用就是判断两个元素是否在同一个集合内,也可以将两个元素所在的集合合并。 举个奇怪的例子。 原理&代码实现+优化 假设这里有一些P主,他们有不同的口味(派别),有摇滚,重金属,古典等等等。 现在我们假设有很多很多种口味,而我们设同[Google] LeetCode 839 Similar String Groups 并查集
Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y. Also two strings X and Y are similar if they are equal. For example, "tars" and "rats" are similar (swapping at positions 0并查集
按秩合并 ·如果连接的循序不好,可能导致找某个节点的代表需要O(n)时间 ·合并时小集合连向大集合 ·这样能保证依次查找时间为O(log n) ·为了减少路径上的重复搜索,压缩查找路上的节点 int find(int x){ if(f[x]==x)return x;//自己就是代表 else return f[x]=find(f[x]);//找并查集
并查集,是用代表元素来维护一个集合的数据结构。可以差不多\(O(1)\)地查询两个元素是否在同一个集合内。 并查集主要通过路径压缩和按秩合并减小复杂度。单独用的话最坏复杂度都是\(O(logn)\)的(虽然只路径压缩的均摊复杂度还是差不多\(O(1)\))。分开讲。 首先是初始化,每个元素各自属真正的骗子(种类并查集)
题目链接 思路: 分成两类:1.村民说真话,2.村民说假话。当村民说是好人的时候,有两种情况,他们都是好人和都是坏人。所以将\(a\ + \ (x + y) ,\ b\ +\ (x + y)\)和\(a, b\)合并为一个集合。同理将\(a,b+(x + y)\)和\(a + (x + y), b\)合并为一个集合。 这个合并的题解:【WC2005】双面棋盘
【WC2005】双面棋盘 题目链接 这天做双面棋盘这道题,发现题解里面大多都是 LCT ,对于线段树套并查集的写法思路讲评很少而且不大清晰,因此有了这一篇题解。 维护联通块的数量,很容易联想到使用并查集,考虑暴力,用并查集记录每个点的连通性,最后统计块数即可。但是如果每次进行格子翻转的1039 银河英雄传说 并查集实现蜘蛛卡牌 有bug
链接:https://ac.nowcoder.com/acm/contest/26077/1039来源:牛客网 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展。 宇宙历七九九年,银河系的两大军并查集(dsu)
一共有 n 个数,编号是 1∼n ,最开始每个数各自在一个集合中。 现在要进行 m 个操作,操作共有两种: M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作; Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中; 输入格式 第一行输入整数 n 和 m并查集
《种类并查集》 对于不能一个并查集不够用了,还需要另一个并查集,但是不能开两个数组作为两个并查集,因为两个并查集之间不能有明确的区分 以样例说明: 贪心思路: 很容易便能想到,我们要使怒气值大的一对人尽量不在同一间监狱里。也就是说,我们要优先考虑怒气值最大的两个人,然并查集(字符串形式)
链接 class Solution { // 使用 Map 来保存每个节点的父节点 Map<String, String> par = new HashMap<>(); public String[] trulyMostPopular(String[] names, String[] synonyms) { // 初始化每个节点 String[] nameArray = Arrays.stream(names)并查集学习笔记
很抱歉这篇博客晚来了(该放在Kruskal前面的)...... 并查集,故名思意,就是用来高效进行合并、查询集合的数据结构,为了方便,我们可以把每一个结点看成树形结构即可。 1.查询 Q1:我们该如何查询某一个结点在哪一个集合呢? A1:我们知道如果需要区分开所有集合,就应该用一个代表来表示这个集合并查集
之前在介绍“图的一些基本概念”中提到了最小生成树,其中一种算法是克鲁斯卡尔(Kruskal's algorithm)算法,里面涉及了对环的判断。我们再回顾下算法的主要流程: 从最小的一个边开始连接,然后再连接第二小的边,且保证新加入的边不能和已经连接的顶点形成环。这样一直重复,最终连接起所有的Codeforces Round #812 (Div. 2) E(并查集)
种类并查集:定义种类之间的关系来判断操作是否进行 题目大意:对于题目给出的一个矩阵,我们可以进行一种操作:swap(a[i][j],a[j][i]) 使得矩阵可以变换为字典序最小的矩阵 思路: 通过扫描整个矩阵,每次都判断a[i][j] 和 a[j][i]是否需要交换 交换的前提就是: 对第i行/第j列操作ZZULI (2022河南萌新联赛 四)
题目描述 分析 读题不认真这个毛病什么时候能改? 我竟然看成最长上升子序列问题了, 而且还把代码写好.......(其实就算看出来是并查集, 我也不会写qwq)赛后借鉴大佬代码, 收获很大 以后看到连通块这个词, 就往并查集的方向想 AC代码 #include <iostream> #include <cstring> usi并查集(集合合并,路径压缩优化)
并查集(路径压缩优化) 摘自acwing算法模板 并查集 并查集的作用: 1.两个集合合并 2.询问两个集合是否在同一个集合中 怎么实现路径压缩? 如果x不是祖宗结点,就让父亲结点 = 祖宗结点 , 最后返回父亲结点 怎么实现集合合并 让a祖宗的结点的父亲等于b结点的结点 代码 #include<iostream并查集模板
P3367 并查集模板。。 #include <bits/stdc++.h> using namespace std; int n, m; #define MAX 1000001 int parent[MAX]; int find(int x) { return (x == parent[x]) ? x : parent[x] = find(parent[x]); } void init() { for (int i = 1; i <= n; i++) {口袋的天空(并查集,生成树)
P1195 将最小生成树的cnt==n-1改为cnt==n-k即可 还是板子题 #include <bits/stdc++.h> using namespace std; #define MAX 100000000 int n, m, k; struct node { int a, b, c; } edges[MAX]; bool cmp(node x, node y) { return x.c < y.c; } int parent[MAX]; int fi并查集(Union Find)
定义 顾名思义(看英文),就是并集,查找,即找到父节点,然后取并集; 题目:LeetCode 547. 省份数量 解决方法:参照B站Up主,塔罗兔 代码: 基础版本 class Solution { public: vector<int> fathers; int find(int i) { while (fathers[i] != i) { i = fathers[i];20220724与佬谈并查集
听佬一席话,胜刷一周题。要抓住一切机会和佬尬聊啊hhh 起源 和佬的尬聊中,偶然提及了并查集。学了一周算法的\(shanzr\)自信地打出他最喜欢的板子: int fa[10010]; int myFind(int x){while(x!=fa[x])x=fa[x]=fa[fa[x]];} void myUnion(int a,int b){fa[myFind(a)]= myFind(b);} 很并查集
一般对于连通性问题,并查集是非常好用的 不仅仅可以维护出是否连通,还可以顺便维护出当前连通块的一些信息,比如直径 有时候并查集的祖先节点不做区分,即合并是认定父子关系是随意的,但是是遇到构建 \(kruscal\) 重构树等情形就需要做出区分,甚至在并查集树上做一些事情,所以一般情况下不蓝桥杯2022省赛I题 - 推导部分和 -带权并查集datastructure
#include <bits/stdc++.h> #define dbg(x) std::cerr << #x << "=" << x << "\n" using i64 = long long; const int N = 1e5 + 9; i64 val[N]; int fa[N]; int find(int x){ if(fa[x] == x) return x; int oAcWing 237. 程序自动分析(并查集+离散化)
题目描述 题目链接 题目思路 先进行离散化(题目中给的数据范围很大,但需要用到的很少),109 ==> 2 × 106 离散化方式: 若要求保序:排序、判重、二分 若不要求保序,用map 本题约束条件的顺序无所谓,则先考虑所有相等的约束条件(一定无矛盾),再考虑不相等的约束条件 相等则放在一个集合中,AcWing 1252. 搭配购买(并查集+01背包)
题目描述 题目链接 题目思路 把所有有边相连的点合并在一起,并且维护总体积和总价值 把每个连通块看成一个物品,之后做一遍01背包 时间复杂度:O(nw) 题目代码 #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 10010; int n,并查集-入门
什么是“并查集”? 首先,并查集是一种(复合)数据结构 并:合并 查:查找 集:以字典为基础的数据结构 实现 class UnionFind { private: // 如果节点相互连通,则他们在同一颗树里 unordered_map<int, int> father; public: bool is_connected(int x, int y) { return