【并查集】hdu 2818
2011-12-05 19:12
176 查看
这题算是并查集的变形,每个blocks需要记录三个信息分别是under(位于x以下的个数),cnt(该block所在堆的积木个数),fa(父亲是谁,注意这个父亲是位于当前block的下面那个)。接着就利用并查集的压缩路径回溯时更新under数组。
#include <map> #include <set> #include <list> #include <queue> #include <deque> #include <stack> #include <string> #include <time.h> #include <cstdio> #include <math.h> #include <iomanip> #include <cstdlib> #include <limits.h> #include <string.h> #include <iostream> #include <fstream> #include <algorithm> using namespace std; #define LL long long #define MIN INT_MIN #define MAX INT_MAX #define pii pair<int ,int> #define mp make_pair #define bug cout<<"here!!"<<endl #define PI acos(-1.0) #define FRE freopen("input.txt","r",stdin) #define FF freopen("output.txt","w",stdout) #define N 30005 int fa ,under ,cnt ; void init(int x){ under[x]=0; cnt[x]=1; fa[x]=x; } int find(int x){//压缩路径,利用回溯 int t; if(x!=fa[x]){ t = find(fa[x]); under[x]+=under[fa[x]]; fa[x]=t; } return fa[x]; } void uni(int x,int y){ int xx = find(x); int yy = find(y); if(xx!=yy){//不在同一个堆 under[xx]=cnt[yy]; cnt[yy]+=cnt[xx]; fa[xx]=yy; } } int main(){ int n; scanf("%d",&n); int i; for(i=0;i<N;i++)init(i); while(n--){ char str[2]; scanf("%s",str); if(str[0]=='M'){ int x,y; scanf("%d%d",&x,&y); uni(x,y); } else { int x; scanf("%d",&x); find(x);//这里还要更新一下,以防中间的block没有更新 printf("%d\n",under[x]); } } return 0; }
相关文章推荐
- HDU 2818 Building Block(带权并查集)
- HDU 2818 Building Block (带权并查集)
- HDU 2818 Building Block(带权并查集)
- hdu 2818 Building Block(并查集)
- hdu 2818 Building Block 并查集 路径压缩
- Hdu 2818 Building Block 加权并查集
- HDU 2818 Building Block (带权并查集)
- hdu 2818 Building Block(并查集,输出一元素下边有多少)
- HDU 2818 Building Block【并查集+根节点偏移量】
- HDU 2818 Building Block (带权并查集)
- POJ 1988 Cube Stacking || HDU 2818 Building Block 带权并查集
- HDU 2818 Building Block (带权并查集)
- hdu 2818(带权并查集)
- hdu 2818 Building Block(带权并查集)
- hdu 2818 Building Block(带权并查集)
- HDU 2818 Building Block 带权并查集
- HDU 2818 Building Block (带权并查集)
- HDU 2818 Building Block(并查集)
- 【HDU 2818】 Building Block 【带权并查集】
- HDU 2818 Building Block (带权并查集)