原題鏈結小 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只得將一些培養皿進行混合,但由於一些生物上的特殊要求,只有含有相同細菌的培養皿才能混合,...