並查集(合併,查詢)

2021-10-02 10:31:26 字數 1911 閱讀 9212

並查集用於管理元素分組情況的資料結構,判斷某一組合是否存在於同一集合(擁有同一性質)

樹形結構實現但非二叉樹,但是通過rank比較可以優化為類似平衡二叉樹

int par[

1000000];

int rank[

1000000];

//統計樹的深度

int size[

1000000];

//統計每一棵樹結點個數

void

init

(int n)

}int

find

(int x)

else

}void

unite

(int x,

int y)

}bool

same

(int x,

int y)

description

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

#include

#include

using

namespace std;

int par[

1000000];

int rank[

1000000];

void

init

(int n)

}int

find

(int x)

else

}void

unite

(int x,

int y)

}bool

same

(int x,

int y)

intmain()

}if(a==2)

}}} cout

}

該題初始化的陣列是3n個,因為有a,b,c三種生物,而3n的作用是將三種生物分開,每個有乙份完整編號[1~n],(n,2n],(2n,3*n],因為有三份於是就可以通過父節點將其聯絡起來進行分組,分類,集合,且使用並查集進行分組和查詢.

並查集實質上是資料的樹狀結構儲存並且可以查詢資料組合是否擁有乙個父節點(存在集合中),然後通過對於陣列的分界來確定元素關係。

實際上真正考察的是我們對於陣列如何分界且維護資料之間的關係

並查集(合併集合,查詢集合中的元素)

定義 合併集合 和 查詢集合中的元素 兩種操作的關於資料結構的一種演算法。演算法 用集合中的某個元素來代表這個集合,該元素稱為集合的代表元。乙個集合內的所有元素組織成以代表元為根的樹形結構。對於每乙個元素 parent x 指向x在樹形結構上的父親節點。如果x是根節點,則令parent x x。對於...

並查集查詢 合併查詢

並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。並查集的核心操作在於查詢與合併,在查詢的時候可以通過遞迴的方式實現路徑的壓縮。inclu...

並查集 合併集合,連通塊中點的數量

練習題 includeusing namespace std const int n 1e6 int n,m int p n 儲存每個點的祖宗節點 返回x的祖宗結點 路徑壓縮 int find int x int main return 0 給定乙個包含n個點 編號為1 n 的無向圖,初始時圖中沒有...