• [US Open 2004][luogu2342] 叠积木 [带权并查集]


    题面

    洛谷传送门

    思路

    学了4年多OI,第一次知道还有带权并查集这个东西

    wtcl

    这个玩意儿的原理和详细实现,可以参考这个博客:带权并查集传送门

    这道题,就是在带权并查集的基础上,加个维护每个集合的大小。

    并查集往每堆积木的底部那个上面合并(也就是根是最底下的积木),合并的时候把儿子的value设定成父亲的size即可

    Code

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cassert>
    #define ll long long
    using namespace std;
    inline int read(){
    	int re=0,flag=1;char ch=getchar();
    	while(ch>'9'||ch<'0'){
    		if(ch=='-') flag=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    	return re*flag;
    }
    int n=30000,m,f[100010],siz[100010],val[100010];
    inline int find(int x){//带权并查集的路径压缩+权值维护
    	if(x==f[x]) return x;
    	int tmp=f[x];
    	f[x]=find(f[x]);
    	val[x]+=val[tmp];
    	return f[x];
    }
    int main(){
    	m=read();int i;
    	char s[10];int t1,t2,x,y;
    	for(i=1;i<=n;i++) f[i]=i,siz[i]=1,val[i]=0;
    	while(m--){
    		scanf("%s",s);
    		if(s[0]=='M'){
    			t1=read();t2=read();
    			x=find(t1);
    			y=find(t2);
    			f[x]=y;//合并到底部
    			val[x]=siz[y];//权值和集合大小的关系
    			siz[y]+=siz[x];
    		}
    		else{
    			t1=read();
    			x=find(t1);
    			printf("%d
    ",val[t1]);
    		}
    	}
    }
    			
    
  • 相关阅读:
    Unity 3D 一个简单的角色控制脚本
    Unity3D 纹理偏移(TextureOffset)浅析
    递归函数的原理
    彻底搞定 C/C++ 指针
    zygote的分裂
    SystemServer分析
    Zygote原理学习
    Vmware Linux虚拟机磁盘扩容方法
    Ubuntu12.04 64bit版本下载Android源码完整教程
    Android2.2源码属性服务分析
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/11782867.html
Copyright © 2020-2023  润新知