并查集(Disjoint Set Union,DSU)
定义:
并查集是一种用来管理元素分组情况的数据结构。
作用:
查询元素a和元素b是否属于同一组
合并元素a和元素b所在的组
优化方法:
1.路径压缩
2.添加高度属性
拓展延伸:
分组并查集
带权并查集
代码如下:
//带有路径压缩的并查集
//一句话并查集(常用)
int dsu(int x){
return x==par[x]?x:(par[x]=dsu(par[x]));
}
//带有路径压缩和高度的并查集
//ranks[i]代表以i为根的树的最大高度,若不存在则为0
int rank[maxn];
int par[maxn];
void init(int n){
for(int i=0;i<n;i++){
par[i]=i;
rank[i]=0;
}
}
int dsu(int x){
if(par[x]==x){
return x;
}else{
return par[x]=dsu(par[x]);
}
}
void union(int x,int y){
int fx=dsu(x);
int fy=dsu(y);
if(fx==fy){
return;
}
if(rank[fx]<rank[fy]){
par[fx]=fy;
}else if(rank[fx]>rank[fy]){
par[fy]=fx;
}else{
par[fy]=fx;
rank[fx]++;
}
}
bool same(int x,int y){
return dsu(x)==dsu(y);
}
poj1182 食物链
//带权并查集解法
/*
模仿矢量计算来处理权值
当我们知道x与祖先x1的关系,y与祖先y1的关系,x与y的关系时,求x1与y1的关系时,使用矢量
计算:
x1->x ->y ->y1
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50010;
int par[maxn],ran[maxn];
int dsu(int x){
if(x==par[x]){
return x;
}else{
int fx=dsu(par[x]);
//一开始将par[x]写成了fx,一直wa
//如果是fx,那么每一次都到最终的根节点,求解ran数组显然不正确
ran[x]=(ran[x]+ran[par[x]]+3)%3;
par[x]=fx;
return par[x];
}
}
int main()
{
int n,m;
int ty,x,y,ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
par[i]=i;
ran[i]=0;
}
while(m--){
scanf("%d%d%d",&ty,&x,&y);
if(x==y&&ty==2){
ans++;
}
else if(x>n||y>n){
ans++;
}
else{
int fx=dsu(x);
int fy=dsu(y);
if(fx==fy)
{
if((ran[x]-ran[y]+3)%3!=ty-1){
ans++;
//这里如果不相等,说明这句话是错误的,continue
//一开始因为没写continue,一直wa
continue;
}
}
par[fx]=fy;
ran[fx]=(-ran[x]+ty-1+ran[y]+3)%3;
}
}
printf("%d\n",ans);
return 0;
}
//分组并查集解法
/*
个人理解带权并查集就是多个并查集,
然后一个set所代表的的关系不仅一种,
所以对每个元素要用多重表示,在这个题目里
就是+i*n来区分每个元素和另一些元素的不同关系
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath> using namespace std; const int maxn = 200000+10;
int par[maxn]; int dsu(int x){
return x==par[x]?x:(par[x]=dsu(par[x]));
}
bool same(int x,int y){
return dsu(x)==dsu(y);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=3*n;i++){
par[i]=i;
}
int cnt=0;
int x,y,ty;
while(m--){
scanf("%d%d%d",&ty,&x,&y);
if(x<=0||x>n||y<=0||y>n){
cnt++;
continue;
}
if(ty==1){
if(same(x,y+n)||same(y,x+n)){
cnt++;
}else{
for(int i=0;i<3;i++){
int fx=dsu(x+i*n);
int fy=dsu(y+i*n);
par[fx]=fy;
}
}
}else{
if(x==y||same(x,y)||same(y,x+n)){
cnt++;
}else{
for(int i=0;i<3;i++){
int fx=dsu(x+i*n);
int fy=dsu(y+(i+1)%3*n);
par[fx]=fy;
}
}
}
}
printf("%d\n",cnt);
return 0;
}
并查集(Disjoint Set Union,DSU)的更多相关文章
- 【算法导论-36】并查集(Disjoint Set)具体解释
WiKi Disjoint是"不相交"的意思.Disjoint Set高效地支持集合的合并(Union)和集合内元素的查找(Find)两种操作,所以Disjoint Set中文翻译 ...
- 并查集(Disjoint Set)
在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题其特点是看似并不复杂, ...
- 【数据结构】【计算机视觉】并查集(disjoint set)结构介绍
1.简述 在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特征点匹配,每对图像的匹配都有一个置信度confidence参数,来衡量两幅图匹配的可信度,当confidence> ...
- 【算法与数据结构】并查集 Disjoint Set
并查集(Disjoint Set)用来判断已有的数据是否构成环. 在构造图的最小生成树(Minimum Spanning Tree)时,如果采用 Kruskal 算法,每次添加最短路径前,需要先用并查 ...
- 树上统计treecnt(dsu on tree 并查集 正难则反)
题目链接 dalao们怎么都写的线段树合并啊.. dsu跑的好慢. \(Description\) 给定一棵\(n(n\leq 10^5)\)个点的树. 定义\(Tree[L,R]\)表示为了使得\( ...
- HDOJ1232 并查集
所谓并查集 并:Union 查:Find 定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单 ...
- Network-POJ3694并查集+LCA
Network Time Limit: 5000MS Memory Limit: 65536K Description A network administrator manages ...
- 并查集(Java实现)
(最好在电脑下浏览本篇博客...手机上看代码不方便) 当时学的时候看的一本印度的数据结构书(好像是..有点忘了..反正跟同学们看的都不一样...)...里面把本文提到的所有情况都提到了,我这里只是重复 ...
- 编程算法 - 食物链 并查集 代码(C)
食物链 并查集 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种 ...
随机推荐
- lsyncd+rsync文件实时同步
1.rsync两端都需要安装 yum -y install rsync 2.提供lsyncd的安装源 rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x ...
- vue 组件之间互相传值:兄弟组件通信
vue 组件之间互相传值:兄弟组件通信我们在项目中经常会遇到兄弟组件通信的情况.在大型项目中我们可以通过引入 vuex 轻松管理各组件之间通信问题,但在一些小型的项目中,我们就没有必要去引入 vuex ...
- spring mvc 整合 druid
环境: ubuntu eclipse maven 一. pom.xml 加入druid 依赖 <!-- https://mvnrepository.com/artifact/com.alibab ...
- 【leetcode】909. Snakes and Ladders
题目如下: 解题思路:天坑题,不在于题目多难,而是要理解题意.题目中有两点要特别注意,一是“You choose a destination square S with number x+1, x+2 ...
- U200-SNMP
U200配置snmp snmp-agent sys-info version v2c snmp-agent community read jkzh snmp-agent trap enable snm ...
- Java排序算法 [选择、冒泡、快排]
选择排序: 简述:从数组的第一个元素开始,依次与其他所有的元素对比,如果比自身大或小(取决于升序或降序)交换位置. package com.sort; import java.util.Arrays; ...
- 分布式系统理论基础2 :CAP
本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...
- PostgreSQL角色和权限
PostgreSQL是通过角色来管理数据库访问权限的,我们可以将一个角色看成是一个数据库用户,或者一组数据库用户.角色可以拥有数据库对象,如表.索引,也可以把这些对象上的权限赋予其它角色,以控制哪 ...
- JAVA StringUtils方法全集
StringUtils方法全集 org.apache.commons.lang.StringUtils中方法的操作对象是java.lang.String类型的对象,是JDK提供 的String类型操作 ...
- (2)C++基本类型
一.整形 short .int. long. long long sizeof查看类型所占的字节数 cout << sizeof(short)<<endl;//2 字节 cou ...