并查集

并查集——Wireless Network

限于喜欢 提交于 2020-01-16 08:18:25
An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B

可持久化并查集

痞子三分冷 提交于 2020-01-16 08:16:46
可持久化数组 可持久化数组是一种可以回退,访问之前版本的数组 是一些其他可持久化数据结构的基石 例如可持久化并查集) 与普通并查集不同的是 这里用到了 按秩合并 不了解可以百度一下 添加链接描述 # include <stdio.h> const int N = 2e5 + 7 ; int rootfa [ N ] , rootdep [ N ] , cnt , tot ; struct Node { int l , r , val ; } T [ N * 40 * 2 ] ; int n ; void insert ( int l , int r , int & now ) { now = ++ cnt ; if ( l == r ) { T [ now ] . val = ++ tot ; return ; } int mid = l + r >> 1 ; insert ( l , mid , T [ now ] . l ) ; insert ( mid + 1 , r , T [ now ] . r ) ; } void modify ( int l , int r , int pre , int & now , int pos , int val ) { T [ now = ++ cnt ] = T [ pre ] ; if ( l == r ) { T [ now ] .

食物链 (带边权并查集)

[亡魂溺海] 提交于 2020-01-14 20:03:36
题目链接 题意:中文题面,无过多客套话,就不说了 思路:参考: https://blog.csdn.net/ccsu_cat/article/details/78089233 把父节点与子节点的关系用向量表示,一共有三种关系, 0代表同类;1代表被根节点吃;2代表吃根节点。 #include <cstdio> #include <iostream> #include <vector> using namespace std; const int maxn = 5e4+100; struct node { int p; int relation; }node[maxn]; void init(int n) { for(int i=1;i<=n;i++) { node[i].p = i; node[i].relation = 0; } } int find(int x) { if(x == node[x].p)return x; int tmp = node[x].p; node[x].p = find(tmp); node[x].relation = (-node[tmp].relation + node[x].relation + 3)%3; return node[x].p; } int main() { int n,m,op,u,v; int ans = 0; scanf("

并查集

北城余情 提交于 2020-01-14 08:23:01
关于并查集的算法,其实也比较简单,主要分为三个步骤,初始化,查找和合并。查找即查找根结点,合并就是合并两个根节点。 并查集通常用于有n个元素的集合应用问题中,在开始时让每个元素构成一个单元素的集合,然后按照一定顺序将属于同一组的元素所在集合合并。 以蓝桥杯中,合根植物一题为例子: 问题描述   w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。   这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。   如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗? 输入格式   第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。   接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)   接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。   格子的编号一行一行,从上到下,从左到右编号。   比如:5 * 4 的小格子,编号:   1 2 3 4   5 6 7 8   9 10 11 12   13 14 15 16   17 18 19 20 样例输入 5 4 16 2 3 1 5 5 9 4 8 7 8 9 10 10 11 11 12 10 14 12 16 14 18 17 18

数据分割-并查集+set

99封情书 提交于 2020-01-12 15:23:20
小w来到百度之星的赛场上,准备开始实现一个程序自动分析系统。 这个程序接受一些形如xi=xj 或 xi≠xj 的相等/不等约束条件作为输入,判定是否可以通过给每个 w 赋适当的值,来满足这些条件。 输入包含多组数据。 然而粗心的小w不幸地把每组数据之间的分隔符删掉了。 他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。 请帮助他恢复这些分隔符。 Input 第1行:一个数字L,表示后面输入的总行数。 之后L行,每行包含三个整数,i,j,e,描述一个相等/不等的约束条件,若e=1,则该约束条件为xi=xj ,若e=0,则该约束条件为 xi≠xj 。 i,j,L≤100000 xi,xj≤L Output 输出共T+1行。 第一行一个整数T,表示数据组数。 接下来T行的第i 行,一个整数,表示第i组数据中的约束条件个数。 Sample Input 6 2 2 1 2 2 1 1 1 1 3 1 1 1 3 1 1 3 0 Sample Output 1 6 看起来就是一个并查集。可是对于不相等的关系,我们只能暴力保存。刚开始我用了一个数组表保存,相等关系的时候都查询一次有没有和之前的不等关系冲突。成功超时。 看题解了解到要用set,的确用set的话查找操作更加方便,空间复杂度也更好。 对每个节点都建立一个set,用于保存不能和他们相等的元素

并查集总结

末鹿安然 提交于 2020-01-12 03:41:47
并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定。不分享出来真是对不起party了。(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例, 杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性问题。比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支。如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了;如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了;如果是3个连通分支,则只要再修两条路…… 以下面这组数据输入数据来说明 4 2 1 3 4 3 第一行告诉你,一共有4个点,2条路。下面两行告诉你,1、3之间有条路,4、3之间有条路。那么整幅图就被分成了1-3-4和2两部分。只要再加一条路,把2和其他任意一个点连起来,畅通工程就实现了,那么这个这组数据的输出结果就是1。好了,现在编程实现这个功能吧,城镇有几百个,路有不知道多少条,而且可能有回路。 这可如何是好? 我以前也不会呀,自从用了并查集之后,嗨,效果还真好!我们全家都用它!

【算法学习笔记】并查集

坚强是说给别人听的谎言 提交于 2020-01-10 19:35:43
\(0.\) 简介 并查集是一种维护节点之间不相交集合关系的一种 树状 数据结构。在算法竞赛中较为常用。并查集的基本形态如下 \(1.\) 一些定义 代表元素 代表元素是指代表这个集合的元素,通常由根节点表示。如上图的4号节点就是这个集合的代表元素。 父亲节点 和其他的树状数据结构类似,父亲节点就是某一节点“上方”的节点。在并查集中,边的方向始终指向父亲节点。 \(2.\) 并查集的功能与基本实现方式 基本的并查集一般实现两种操作:合并集合,查找某个节点所在集合的代表元素。 并查集的初始化 一般的我们在初始状态时将每个元素看做独立的集合,即每个元素所在的集合就是自己。 for(rg int i=1;i<=n;i++) fa[i]=i; 上面代码中 \(fa[\ ]\) 就简单的实现了一个并查集。其中 \(fa[i]\) 代表编号为 \(i\) 的元素的父亲节点。 查找代表元素 并查集的实现结构是每个节点有一个指针指向父亲节点,代表元素(根)的指针指向自己。 所以可以递归地查找代表元素 inline int find(int x){ return fa[x]==x?x:find(fa[x]); } 上面的代码就实现了查找代表元素的操作。如果一个节点的父亲是他自己,那么这个节点就是并查集的代表元素,否则往上方跳,直到找到代表元素为止。 合并集合 zcy大神在某个地方讲过

并查集——The Suspects

六眼飞鱼酱① 提交于 2020-01-10 07:34:36
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others. In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation

POJ-1611-The Suspects(并查集)

拟墨画扇 提交于 2020-01-09 16:43:40
The Suspects Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others. In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard

算法导论——最小生成树:Kruskal算法(利用了并查集)

醉酒当歌 提交于 2020-01-07 15:11:19
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> package org.loda.graph; import org.loda.structure.MinQ; import org.loda.structure.Queue; import org.loda.util.In; /** * * @ClassName: KruskalMST * @Description:Kruskal最小生成树算法 * @author minjun * @date 2015年5月25日 下午10:50:01 * */ public class KruskalMST { private Queue<Edge> mst; private double weight; public KruskalMST(WeightGraph g){ int v=g.v(); mst=new Queue<Edge>(); MinQ<Edge> q=new MinQ<Edge>(); UF uf=new UF(v); //将所有边添加到优先队列中 for(Edge edge:g.edges()){ q.offer(edge); } while(!q.isEmpty()){ Edge edge=q.poll(); int a=edge.oneSide(); int b=edge.otherSide(a);