在並查集問題的處理中有幾種常見的實用方法,下面介紹第一種:虛空節點(我這麼叫,莫黑)。
結合例題身體好~
洛谷oj 10.19比賽題目宗教信仰 religion
題目描述 description
在一片大陸上有許多個國家和許多個宗教。每乙個國家在某一時刻僅有1個官方信仰的宗教。
這些宗教可能會互相兼併,合成乙個宗教。某個國家也可能在某一時刻改信乙個宗教。
現在給出宗教兼併和國家改宗的大事表,以及若干個詢問,詢問在當前時刻2個國家是否信仰乙個宗教。
每個國家在開始時,都信仰著不同的宗教。
輸入輸出格式 input/output
輸入格式:
第一行 1 個整數 n 表示國家數量。
第二行 1 個整數 q 表示一共有q個大事及詢問。
以下 q 行 每行形式如下:
1 a b 表示 a 國所信仰的宗教與 b 國所信仰的宗教 合併為 1 個宗教;
2 a b 表示 a 國改為信仰 b 國所信仰的宗教;
3 a b 表示查詢 a 國 和 b 國 現在是否信仰同乙個宗教;
//如果 1 2 3信仰a宗教,4 5信仰b宗教,那麼執行2 1 4 後,2 3國信仰a宗教,1 4 5國信
//仰b宗教
輸出格式:
對於每乙個 詢問 輸出 'yes' 或 'no' 來回答詢問,分別表示是同乙個宗教或不是同乙個宗教.
input56
1 3 4
1 2 4
3 2 4
2 5 2
3 1 5
3 3 5
output
yesno
yes好了,分析一下,顯然是並查集對吧,那麼 3操作是查詢,1操作路徑壓縮合併,2嗎,是什麼呢。。。。。。
我們很快會想到:如果只改這麼乙個點的話,那麼如果這是個根(老祖宗,路徑壓縮後的根節點),那麼我一改,豈不難辦了?
這樣好了,我們每乙個點剛開始的時候都把他父親設成乙個根本不存在的點好了~~這樣一來原來的根就變成了現在我們的某虛空節點的乙個兒子了,只要合併的時候只把虛空節點的兒子接到別處就好了,2333
所以就這麼a了,可能講不大明白,看**一定能弄明白。
下面是某弱逼的弱渣程式:
1 #include2 #include3view codeusing
namespace
std;
4int
n,m;
5int fa[2000500];6
int find(intx)7
11int
main()
1219
while(m--)
2029
else
if(p==2)30
33else
3439}40
return0;
41 }
並查集專題
洛谷p3144 usaco16open 關閉農場關閉農場 離線的反著的並查集 看看在不在乙個集合內 include include include include using namespace std int n,m int f 99999 a 3009 3099 b 3999 int ans 1...
並查集專題講解
並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題。例如 1,合併兩個集合,複雜度是o 1 2,查詢乙個元素在哪個集合裡面,複雜度o 1 3,查詢兩個元素是否在同乙個集合裡面。1,初始化 每個結點的父親結點首先設為它本身。void init 2,路徑壓縮 解決特殊情況下的樹的層次深而...
並查集專題總結
並查集是乙個高效的資料結構,最簡單的作用是用來判斷圖中的兩個點是不是屬於同乙個連通分量。我們可以將圖中的每乙個連通分量看成乙個集合,每個集合都有乙個特徵值。比如的特徵值為1,那麼記f 1 f 2 f 3 f 4 1,則這樣可以通過判定兩個點的f值來判定是不是屬於同乙個連通分量。然後,我們用樹的形式來...