用自己的理解來寫好了
有些地方可能不對
不定時更新理解
操作主要為三步
一 初始化
void init()
}
二 查詢
這個為路徑壓縮 就是每次查詢時更新 查詢節點(x) 上面所有節點直接使他們連向根節點
每次查詢更新
int find(int x)
另一種路徑壓縮 不過麻煩了些 作為理解
int find(int x)
int temp;
while (t != x)
return x;
}
非路徑壓縮的查詢
int find(int x)
int find(int x)
三 合併
void unite(int x,int y)
else
}
帶防退化的合併 防退化:使較短的樹連到較長的樹上
合併:讓兩個 查詢節點 的其中乙個根節點指向另乙個
基本的並查集也就這些了
下面通過分析食物鏈這個典型題 加深對並查集的理解
帶權(關係)並查集
動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b, b吃c,c吃a。
現有n個動物,以1-n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。
有人用兩種說法對這n個動物所構成的食物鏈關係進行描述:
第一種說法是」1 x y」,表示x和y是同類。
第二種說法是」2 x y」,表示x吃y。
此人對n個動物,用上述兩種說法,一句接一句地說出k句話,這k句話有的是真的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。
1) 當前的話與前面的某些真的話衝突,就是假話;
2) 當前的話中x或y比n大,就是假話;
3) 當前的話表示x吃x,就是假話。
你的任務是根據給定的n(1 <= n <= 50,000)和k句話(0 <= k <= 100,000),輸出假話的總數。
input
第一行是兩個整數n和k,以乙個空格分隔。
以下k行每行是三個正整數 d,x,y,兩數之間用乙個空格隔開,其中d表示說法的種類。
若d=1,則表示x和y是同類。
若d=2,則表示x吃y。
output
只有乙個整數,表示假話的數目。
sample input
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
sample output
3
#include
#define maxn 50005
int par[maxn],rank[maxn];
int n,k;
void init()
}int find(int
x)bool unite(int
x,int
y,int tye)
else
}int main()
printf("%d\n",ans);
return
0;}
算是對不斷加入元素關係之間的更新
tye為關係 這題的關係有兩種 一種是 0 (同類) 1(相鄰作用關係) 根據題中d的條件轉化為 0 1 兩種 3為三類動物 同類的題可直接套模板
並查集 總結
自己學完後總結一下吧,並查集,我的理解就是乙個查詢與合併,用乙個find函式來查詢自己的祖先也就是根節點,在這過程中還可以進行路徑壓縮,就是讓這個點直接變到根節點之下,還有就是合併,找出這兩個點的根節點,如果根節點不相同的話,就將乙個根節點放到另乙個根節點下面。這道題的就是用並查集做,找出總共有幾個...
並查集總結
注 此博文是在老師上課之後總結的,屬於課堂筆記,大部分摘自老師提供的課件。並查集總結總結兩點就是 並 和 查 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組...
並查集總結
並查集是一種管理元素分組的資料結構,是使用樹形結構實現的 作用 1 查詢元素a,b是否屬於同一組 2 合併元素a,b所在的組 只能進行合併,無法進行分割 注意 為避免退化發生,需進行以下操作 1 對於每棵樹,記錄數的高度rank 2 合併時如果兩棵樹的rank不同,從rank小的向rank大的連邊 ...