一、基本性質
1.在基於並查集的基礎上增加記錄陣列_rank,表示i與其同集合根節點的關係
二、例題講解
2.1【食物鏈 poj - 1182】——vjudge題目鏈結
題意:動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a**, 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:31
題目分析:
rank[x] = 0:表示x與f[x]為同種生物
rank[x] = 1:表示x吃f[x]
rank[x] = 2:表示x被f[x]吃
以下為accepted**
#include #include #include using namespace std;
const int n = 54014;
int f[n], _rank[n];
void init(int n);
int get_f(int x);
bool merge(int d, int x, int y);
int main()
if(d == 2 && x == y)
if(!merge(d, x, y))
}printf("%d\n", cnt);
return 0;
}void init(int n)
}int get_f(int x)
bool merge(int d, int x, int y)
else
}else
else
}}
2.2【por costel and the match gym - 100923h——vjudge題目鏈結】
題意:已知有n個戰士,分屬於兩個紅、藍陣營,現輸入m條敵對關係,當本條關係資訊與之前的真的關係資訊衝突,則認為本條關係資訊為假(即先輸入的敵對關係優先為真)
input:
第一行輸入t,代表t組測試資料
每組測試資料第一行輸入整數n和m,表示n個戰士,m條敵對關係判斷語句
之後輸入m行,每行含有整數x和y,表示認為x和y為敵對關係(即陣營不同)
output:
輸出m行,每行輸出」yes」或」no」(不含引號),表示判斷所得本條語句的真假
sample input:
13 3
1 22 3
1 3sample output:
yesyes
no題目分析:
rank[x] = 0:表示x與f[x]為朋友(即屬於同一陣營)
rank[x] = 1:表示x與f[x]為敵人(即分屬不同陣營)
以下為accepted**
#include #include #include using namespace std;
const int n = 104014;
int f[n], _rank[n];
void init(int n);
int get_f(int x);
bool merge(int x, int y);
int main()
}return 0;
}void init(int n)
}int get_f(int x)
bool merge(int x, int y)
else
return true;
}
2.2例題感悟:1.基於並查集;2.認真仔細尋找rank[i]表示含義 並查集例題
題目描述 假如已知有n個人和m對好友關係 存於集合r 如果兩個人是直接或間接的好友 好友的好友的好友 則認為他們屬於同乙個朋友圈。請寫程式求出這n個人裡一共有多少個朋友圈。輸入 輸入包含多個測試用例,每個測試用例的第一行包含兩個正整數 n m,1 n,m 100000。接下來有m行,每行分別輸入兩個...
並查集例題
找出根節點,如果只有乙個節點,根節點是自己 作迴圈,如果父節點不是自己,一直迴圈 public int find int x return x public void union int x,int y parent rootx rooty count 並查集自己的理解 剛開始每個節點都是看作單獨的...
並查集講解
所謂並查集,實際上可以認為是對集合的合併與查詢,所以下面從集合開始講解。假設有集合a 1 2 3 4 5,集合b 6 7 8 9 0 假設此時有乙個條件導致a中的隨便乙個數與b中的隨便乙個數在乙個集合內,那麼很顯然ab將會合併成乙個更大的集合。接下來考慮演算法 對乙個陣列f 50 來說,先對其進行初...