zoukankan      html  css  js  c++  java
  • Almost Union-Find (并查集+删除元素)题解


    思路:

    当时只有暴力的思想,1、3都很好达到,只要加一个sum[ ]和num[ ]就可以,但是2比较麻烦,不知道谁以p为根,就想直接扫描然后一个个和p脱离关系,果然超时emmm。通常的想法是我们先用一个数组id[ ]表示p所代表的代号也就是说p当前的根为:

    pre[ id[p] ]

    所以当p被2操作时,我们只要改变它的id[p](比如 id[p]=++n),我们就可以让p有一个新的pre[ ]表示,而不用改变原来的根的表示,所以当后面的操作又用到p时,现在的 pre[ id[p] ] 已经不是之前那个了。

    详细可以看代码:

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #include<iostream>
    #include<map>
    #define N 200010
    #define HASH 10000
    using namespace std;
    int pre[N],num[N],id[N];
    long long sum[N];
    int find(int a){
    	int r=a;
    	while(r!=pre[r]){
    		r=pre[r];
    	}
    	int i=a,j;
    	while(i!=pre[i]){
    		j=pre[i];
    		pre[i]=r;
    		i=j;
    	}
    	return r; 
    }
    void init(int n){
    	int i;
    	for(i=0;i<=n;i++){
    		pre[i]=i;
    		sum[i]=i;
    		id[i]=i;
    		num[i]=1;
    	}
    }
    int join(int p,int q){	//合并两个根(注意:方向必须是这样) 
    	int fp=find(id[p]);
    	int fq=find(id[q]);
    	pre[fp]=fq;
    	num[fq]+=num[fp];
    	sum[fq]+=sum[fp];
    }
    int main(){
    	int n,m,c,p,q,i;
    	while(scanf("%d%d",&n,&m)!=EOF){
    		init(n);
    		while(m--){
    			scanf("%d",&c);
    			if(c==1){
    				scanf("%d%d",&p,&q);
    				if(find(id[p])!=find(id[q]))
    				join(p,q);
    			}
    			else if(c==2){
    				scanf("%d%d",&p,&q);
    				if(find(id[p])!=find(id[q])){
    					num[find(id[p])]--;	//脱离与原根关系 
    					sum[find(id[p])]-=p;
    					id[p]=++n;	//重新申请一个id 
    					pre[id[p]]=id[p];	//初始化 
    					sum[id[p]]=p;
    					num[id[p]]=1;
    					join(p,q);	//建立新关系 
    				}
    			}
    			else{ 
    				scanf("%d",&p);
    				printf("%d %d
    ",num[find(id[p])],sum[find(id[p])]);
    			}	
    		}
    	} 
    	return 0;
    }



  • 相关阅读:
    PythonStudy——greenlet 协程
    PythonStudy——事件 Event
    PythonStudy——单线程并发的实现
    2015年的总结
    kylin一种OLAP的实现
    分布式消息队列的使用kakfa
    第一次听到了docker
    Hive分布式的数据仓库
    dubbo服务框架学习
    Storm实时计算框架的编程模式
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9409139.html
Copyright © 2011-2022 走看看