POJ 1988 Cube Stacking(並查集+路徑壓縮)
阿新 • • 發佈:2017-07-11
trac ref nio space == using n) scan 累加
題目鏈接:
id=1988">POJ 1988 Cube Stacking
並查集的題目
【題目大意】
有n個元素,開始每一個元素自己 一棧。有兩種操作,將含有元素x的棧放在含有y的棧的頂端,合並為一個棧。
另外一種操作是詢問含有x元素以下有多少個元素。
用sum數組儲存每一個棧中的元素個數。每次合並的時候將sum加到 父親節點。也就是每一個棧的最底部。
用under數組儲存當前節點以下有多少元素。每次合並的時候,就能夠將頂端元素的under賦值為父節點也就是棧最底部的sum。
void Union(int x,int y){ int xr = find(x); int yr = find(y); if(xr==yr) return; father[xr]=yr; under[xr]=sum[yr]; sum[yr]+=sum[xr]; }
在查詢的時候,運用遞歸的思想。從底部往上加under。
int find(int x){ if(x==father[x]) return father[x]; int tmp = find(father[x]); under[x]+=under[father[x]]; //細致想想 father[x]=tmp; return tmp; }
【源碼】
#include <iostream> //父親節點在棧的底部 #include <cstdio> using namespace std; const int maxn = 30000+10; int father[maxn]; int under[maxn]; int sum[maxn]; void init(){ for(int i=0;i<maxn;i++){ father[i]=i; under[i]=0; sum[i]=1; } } int find(int x){ if(x==father[x]) return father[x]; int tmp = find(father[x]); under[x]+=under[father[x]]; father[x]=tmp; return tmp; } void Union(int x,int y){ int xr = find(x); int yr = find(y); if(xr==yr) return; father[xr]=yr; under[xr]=sum[yr]; sum[yr]+=sum[xr]; } int main(){ int n; while(scanf("%d",&n)!=EOF){ char ch; int a,b; init(); for(int i=0;i<n;i++){ scanf(" %c",&ch); if(ch=='M'){ scanf("%d%d",&a,&b); Union(a,b); } else{ scanf("%d",&a); int x=find(a); //僅僅是用來累加一下under printf("%d\n",under[a]); } } } return 0; }
POJ 1988 Cube Stacking(並查集+路徑壓縮)