第三次複習了,最經典的並查集
題意:動物王國中有三類動物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),輸出假話的總數。
/*n個動物 k句話 有一種迴圈a吃b 吃c c吃a 開始不知道n種動物關係是什麼
兩種詢問:d=1 x y為同類 d=2 x吃y 判斷假話條數(關鍵之違背之前的關係)
並查集可以很好解決的滿足區間傳遞關係的區間合併問題,注意一般是多棵樹
*/#include
#include
#include
using
namespace
std;
const
int max=50010
;int
fat[max],ran[max];
void init(int n)//
初始化重要
return;}
int find(int x)//
找尋父節點+路徑壓縮
int union(int typ,int x,int y)//
區間並與查詢
fat[x1]=y1;//
連線兩父節點
ran[x1]=(-ran[x]+typ-1+ran[y]+3)%3;//
使用類似向量方法來計算權值,雖然題目只有兩個,但是會出現被吃這種情況,所以要變成3種情況,注意一定要處理負數的情況
return0;
}int
main()
printf(
"%d\n
",ans);
return0;
}
並查集,帶權並查集
題意 ignatius過生日,客人來到,他想知道他需要準備多少張桌子。然而一張桌子上面只能坐上相互熟悉的人,其中熟悉可定義成為a與b認識,b與c認識,我們就說a,b,c相互熟悉 例如a與b熟悉and b與c熟悉,d與e熟悉,此時至少需要兩張桌子。輸入 t表示樣例個數,n表示朋友個數,朋友從1到n編號...
並查集和帶權並查集
並查集是乙個很高效演算法,理解起來也很簡單,寫起來更簡單。fat i i 找到乙個點的祖先 int findfat int x 二中的方法肯定不好,因為如果資料比較極端,那麼並查集就退化成乙個鏈了 如果加入了路徑壓縮,並查集這個演算法就更高效了。int findfat int x 遞迴寫法 int ...
並查集與帶權並查集
1.找點的祖先 fa i i 並查集的快主要在於路徑壓縮。1 遞迴寫法 int find int x 2 非遞迴寫法 int find int x return r 2.合併 合併2者的集合。void merge int x,int y 3.帶權並查集 一般是存下一些2者之間的具體的數量關係或者是統...