並查集入門 高階

2021-09-10 08:35:52 字數 1729 閱讀 4815

入門解釋:

高階解釋:

入門篇模板

#define arr_size 100

int pre[arr_size];

int deep[arr_size];

void init()

}int pre_find(int x)

return pre_find(pre[x]); // 遞迴查詢

}void unite(int x, int y)

if (deep[i] > deep[j])

else

pre[i] = j;

}}

高階篇解題

食物鏈動物王國中有三類動物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

3

#define arr_size 100

int pre[arr_size]; // 存父親節點

int r[arr_size]; // 存與根節點的關係

// r[x] = 0 : x 與根節點同類

// r[x] = 1 : x 被根節點吃

// r[x] = 2 : x 吃根節點

int n, k;

void init()

}int find(int x)

int tmp = pre[x];

pre[x] = find(pre[x]); // 增加路徑壓縮演算法

r[x] = (r[x] + r[tmp]) % 3; //回溯由子節點與父節點的關係和父節點與根節點的關係找子節點與根節點的關係 %3

return pre[x];

}void unite(int x, int y, int d)

int main()

else if (find(a) == find(b))

else

} printf("sum is [%d]\n", sum);

return 0;

}

並查集高階

n 個孤立點,m 次加邊操作,設 l i,j 表示結點 i 和 j 最早在第 l i,j 次操作後連通。在 m 次操作後,求出 sum n sum n l i,j 的值。解法 quad 並查集的時候記錄子樹大小即可。n 個孤立點,m 次加邊操作,q 次詢問,每一次問 u 和 v 最早在第幾次操作後連...

並查集入門

簡述 其實並查集顧名思義就是有 合併集合 和 查詢集合 兩種操作的關於資料結構的一種演算法。並查集演算法不支援分割乙個集合。演算法 用集合中的某個元素來代表這個集合,該元素稱為集合的代表元。乙個集合內的所有元素組織成以代表元為根的樹形結構。對於每乙個元素 parent x 指向x在樹形結構上的父親節...

並查集入門

1.並查集是一種樹形的資料結構,顧名思義,它用於處理一些不交集的合併及查詢問題。它支援兩種操作 查詢 find 確定某個元素處於哪個子集 合併 union 將兩個子集合並成乙個集合。初始化 void makeset int size 查詢 int find int x 合併 void unionse...