• C++ P3367 【模板】并查集


    本来打算尝试学一下LCA的,但是发现似乎离线算法需要预备知识:并查集,于是尝试学了一下并查集。

    并查集的思想:
    有时候我们需要对一个集合进行操作,比如判断某个数是否属于另一个数所属于的某个集合,那么我们就可以用这样的思想:
    每一个集合只存一个代表,集合中的其他元素都连接这个代表,而这个集合中除了代表连接着其他元素,其他元素不互相连接。
    这样的话,速度就快很多了。比如原来我们可能需要这样:
    对于一个集合大小为n的集合,时间复杂度为O(n)
    而使用并查集后,复杂度为O(1)
    代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int data[10001];
    int find(int k){
    	if(data[k]==k)return k;
    	return data[k]=find(data[k]);
    }
    int main(){
    	int n,m;
    	cin>>n>>m;
    	for(int i=1;i<=n;i++){//n个元素 
    		data[i]=i;
    	}
    	for(int i=0;i<m;i++){//m个操作 
    		int a,b,c;
    		cin>>a>>b>>c;
    		if(a==1){
    			data[find(data[b])]=find(c);//将b的爸爸变成c的爸爸  注意,这里需要让b的最大的爸爸的爸爸变成c的最大的爸爸。在find的同时就会更新每个元素的爸爸为当前的总爸爸(return时的处理) 
    		}else if(a==2){
    			if(find(b)==find(c)){
    				cout<<"Y"<<endl;
    			}else{
    				cout<<"N"<<endl;
    			}
    		}
    	}
    }
    

    关键的方法就是find(int k)方法。重点是对这个方法的理解,剩余的内容主要是输入的进行。对这个方法的理解可以看一下洛谷的题解。

    我对find(int k)方法的理解:
    第一行{ if(data[k]==k)return k; }:k的值为要查询的值,方法本身的用处是查找k的最大的父亲,那么这一行的意思就是:如果k的父亲是他自己,就返回他自己。
    第二行{ return data[k]=find(data[k]); }:如果k的父亲不是k自己,就查找 k的父亲 的最大的父亲,并设置k的最大的父亲为 k的父亲 的最大的父亲。这样就可以得出,从k到k次一级的父亲都会直接变成最大的父亲的儿子。

    题目(洛谷):https://www.luogu.org/problemnew/show/P3367
    题解(洛谷):https://www.luogu.org/problemnew/solution/P3367

  • 相关阅读:
    OpenGL ES multithreading and EAGLSharegroup
    NSRange用法(转)
    多测师肖老师_mysql之视图(10.1)
    多测师肖老师__三表(9.1)
    多测师肖老师__多表练习(8.1)
    多测师肖老师__多表讲解(7.9)
    多测师肖老师_mysql之单表练习(7.5)
    多测师肖老师__单表建表和练习(1.8)
    多测师肖老师_mysql之单表和多表题(9.2)
    多测师肖老师___分享杭州面试题
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680732.html
Copyright © 2020-2023  润新知