之前暑假集訓的時候學了一下並查集,但是那個時候完全搞不懂種類並查集(帶權並查集)的路徑壓縮以及兩個節點關系的合並。
現在有重新學習了一下,算是對種類並查集有了一些粗淺的理解了吧。
附上一個寫的很好的博主鏈接:
https://blog.csdn.net/c0de4fun/article/details/7318642
關於路徑壓縮:
int Find(int x) { if(x == father[x]) return x; int temp = father[x]; father[x] = Find(father[x]); rela[x] = (rela[x] + rela[temp]) % 3; return father[x]; }
其實之前我就不是很懂,為什么要設一個temp存儲father[x]的值,不應該像下面的代碼這樣的嗎。(現在想想我好蠢。。
int Find(int x) { if(x == father[x]) return x; father[x] = Find(father[x]); rela[x] = (rela[x] + rela[father[x]]) % 3; return father[x]; }
但是father[x]跟Find(father[x])的值有可能是不一樣的。
而路徑更新一定是當前節點與根節點的關系+當前節點父節點跟根節點的關系取模才對。(具體證明可以看我上面推薦的博客。
所以我的想法就很可笑。
之后我之前還有個問題就是我之前是寫成這樣的
int Find(int x) { if(x == father[x]) return x; int temp = father[x]; rela[x] = (rela[x] + rela[temp]) % 3; father[x] = Find(father[x]); return father[x]; }//把father[x]的更新放在rela更新的后面
這樣是有問題的。這樣的話,當前節點父節點跟根節點的關系可能就是沒有更新之前的錯誤關系,就會導致程序錯。
關於兩個合並節點之間的更新的話,其實就是窮舉找規律得出來的。並不是特別難懂的東西,在這里就不提及了
