POJ 1988 CUBE STACKING(并查集)

来源:互联网 发布:elk windows 搭建 编辑:程序博客网 时间:2024/06/03 03:30

原文:http://blog.acmj1991.com/?p=659

题意:给你M u v 为将u所在栈的数据移动v所在栈的顶端
C u查询u所在的栈中在u后面有多少个数字

思路:并查集的应用和建树的过程差不多从叶子节点往上堆积,开始的时候没有压缩用了1000+ms
后来压缩了一下用了 200+ms

#include<stdio.h>#include<string.h>#include<iostream>using namespace std; #define maxN 30010#define maxM 200010int nu,pre[maxN],num[maxM],f[maxM],ke[maxM]; int find(int x){    if(pre[x]==0){        pre[x]=++nu;        num[nu]=1;        return nu;    }    x=pre[x];    int temp,p=x,cnt=0,sum=0;    while(f[p]!=0){        cnt+=ke[p];        p=f[p];    }    while(f[x]!=0){        sum+=ke[x];        ke[x]+=cnt-sum;        temp=f[x];        f[x]=p;        x=temp;    }    return p;}int sum(int x){    int cnt=0;    x=pre[x];    while(x!=0){        cnt+=ke[x];        x=f[x];    }    return cnt;} int main(){    int px,py,n,u,v,s;    char str[10];    scanf("%d",&n);    while(n--){        scanf("%s",str);        if(str[0]=='C'){            scanf("%d",&u);            printf("%d\n",sum(u));        }else{            scanf("%d%d",&u,&v);            px=find(u);            py=find(v);            f[px]=f[py]=++nu;            ke[px]=num[py];            num[nu]=num[px]+num[py];        }    }}