小z的洞穴之旅 QDUOJ 並查集 連通塊

2022-03-16 22:17:27 字數 1244 閱讀 4050

原題鏈結

小 z 同學在某個閒暇的週末決定去野外探險一波,結果在叢林深處中誤打誤撞進入了乙個神秘的洞穴,雖然洞穴中光線昏暗,但小 z 憑藉其敏銳的眼力立刻辨認出這是乙個迷宮狀洞穴,並且他還發現了乙個現象:該洞穴中時不時會有乙個牆塊自行坍塌,每個牆體坍塌後其所在單元格即變為空地,其坍塌過程中所產生的塵土也會隨之傳到該牆體相連的各個空地處,於是他很好奇,對於每一次牆塊的坍塌,所產生的塵土會遍及到多大的空白區域?

這個題很像《啊哈!演算法》中的島嶼問題,但是如果每次有牆倒塌後都進行bfs一次的話會超時,所以這裡要先進行預處理,這裡預處理是用bfs來掃,把聯通的塊使用並查集歸併到一起(對於二維的資料,需要轉化為一維的資料,**中的getid函式就是幹這個的)。之後每次有牆倒塌就檢視周圍四個位置, 詳情見**實現。

在此也感謝zyb學長的題解!當時沒有嘗試做,很懺愧。

#include#include#include#include#includeusing namespace std;

const int maxn=5e3+7;

struct notetre[maxn*maxn];

struct node;

int n, m;

char mp[maxn][maxn];

int go[4][2]=;

queueq;

inline int getid(int x, int y)// getid()將二維點(x,y)對映為一維的數值

int find(int x) //尋找父節點,並且進行路徑壓縮

void merge(int u, int v) //這裡合併時按照各自集合中點的個數來進行合併

else

}void bfs(int x, int y, int rt) //預處理中的一部分

, tmp;

int tx, ty, id;

q.push(h);

while(!q.empty()) }

}void init() //預處理的主程式

for(int i=1; i<=n; i++)

for(int j=1; j<=m; j++) }

int main()

mp[x][y]='.'; //最後還需要維護原始的mp

printf("%d\n", tre[find(id)].sum); //返回當前點(x,y)所在的連通塊的大小

} return 0;

}

並查集之旅

最基礎的並查集。include using namespace std int s 50005 hight 50005 void init int n int getroot int x void merge int x,int y else int main for int i 1 i n i c...

CSU 2125小Z的培養皿(並查集)

小z高中的時候特別喜歡生物,在一次做實驗的過程中,小z配置了n個培養皿,每個培養皿中有著若干種類的細菌,但由於實驗室的培養皿數量有限,老師要求小z盡可能少地使用培養皿。為此,小z只得將一些培養皿進行混合,但由於一些生物上的特殊要求,只有含有相同細菌的培養皿才能混合,否則細菌將全部死亡。這時候小z想請...

CSU 2125小Z的培養皿(並查集)

感謝大佬 description 小z高中的時候特別喜歡生物,在一次做實驗的過程中,小z配置了n個培養皿,每個培養皿中有著若干種類的細菌,但由於實驗室的培養皿數量有限,老師要求小z盡可能少地使用培養皿。為此,小z只得將一些培養皿進行混合,但由於一些生物上的特殊要求,只有含有相同細菌的培養皿才能混合,...