日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

带权并查集-Building Block

發(fā)布時(shí)間:2025/3/12 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 带权并查集-Building Block 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目:

John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1…N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:

M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
C X : Count the number of blocks under block X

You are request to find out the output for each C operation.
Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
Output
Output the count for each C operations in one line.
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2

分析與解答:

題意:

N:有1到N個(gè)數(shù)
M x y :把x所在的堆放到y(tǒng)所在的堆上面
C x:輸出x下面有幾個(gè)數(shù)

這個(gè)博客說鋼管串磚塊啟發(fā)了我。。
https://blog.csdn.net/viphong/article/details/51934799
我覺得這一點(diǎn)不美觀,我更喜歡用竹簽串魚蛋描述

我們直接看復(fù)雜的過程,就是這兩串魚蛋我們把他擼到一串的過程。。

如果把第二串?dāng)]到第一串上的話,正常的話我們肯定是把第二串的兩個(gè)魚蛋拔出來,然后按到第一串上,也就是下面這個(gè)樣子。。

現(xiàn)在題目問我某個(gè)魚蛋底下有幾個(gè)魚蛋

假設(shè)所有竹簽一開始只有一個(gè)魚蛋

我們先看看怎么移動(dòng)

移動(dòng)的話我們先找兩個(gè)串最底下的那個(gè)魚蛋
假設(shè)d[x]是指魚蛋x下邊有幾個(gè)魚蛋
r[x]是指魚蛋x所在的串上一共有幾個(gè)魚蛋,這里我們讓最底下的魚蛋存他那一串魚蛋的總數(shù)

注意我們轉(zhuǎn)移的時(shí)候是連根拔起,必須找到最底下的魚蛋,再移動(dòng)(因?yàn)橐粋€(gè)集合的緣故)
我們找到分別是兩串魚蛋最底下的那個(gè)魚蛋fx,fy
就可以更新d[fx],d[fx]=r[fy]
然后我們更新r[fy],現(xiàn)在r[fy]=r[fx]+r[fy](注意觀察圖像)

那當(dāng)然了,他不可能只問最底下的魚蛋,他可能問串中間的,此時(shí)我們就通過find函數(shù)改中間的魚蛋下面的魚蛋數(shù)d[x]

比如新的d[2]=老的d[2]+新的d[4]=1+r[fy]=1+2=3

find用的遞歸,也就是說會(huì)先找到最底下的魚蛋,然后依次返回就把最底下的上一個(gè)魚蛋的d[]給更新了

所以為什么我們輸出d[x]前先調(diào)用一下find,目的就是為了更新

#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAX 30000+5 using namespace std; int pre[MAX]; int d[MAX]; int r[MAX]; int init(){ for(int i=0; i<=MAX; i++){pre[i]=i;d[i]=0;r[i]=1;} } int Find(int x){int fx;if(x==pre[x]) return x;fx=pre[x];pre[x]=Find(fx);d[x]=d[x]+d[fx];//return pre[x]; } void Union(int x, int y){int fx=Find(x), fy=Find(y);if(fx==fy) return;pre[fx]=fy; d[fx]=r[fy];//r[fy]+=r[fx]; //return; } int main(){int P;scanf("%d",&P);init();while(P--){char op[5];int x, y;scanf("%s",op);if(op[0]=='M'){scanf("%d%d",&x,&y);Union(x,y);}else{scanf("%d",&x);Find(x);printf("%d\n",d[x]);}}return 0; }

總結(jié)

以上是生活随笔為你收集整理的带权并查集-Building Block的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。