並查集 親戚

2021-07-23 23:36:37 字數 1155 閱讀 1541

一、題目描述

親戚(relation.cpp)

時間限制: 1 sec  記憶體限制: 64 mb

題目描述

若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易。 現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。 我們規定:如果x和y是親戚,y和z是親戚,那麼x和z也是親戚;如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。

輸入第一行:三個整數n,m,p,(n≤5000,m≤5000,p≤5000),分別表示有n個人,m個親戚關係,詢問p對親戚關係。 以下m行:每行兩個數mi,mj,1≤mi,mj≤n,表示ai和bi具有親戚關係。 接下來p行:每行兩個數pi,pj,詢問pi和pj是否具有親戚關係。

輸出p行,每行乙個』yes』或』no』。表示第i個詢問的答案為「具有」或「不具有」親戚關係。

樣例輸入

6 5 3

1 21 5

3 45 2

1 31 4

2 35 6

樣例輸出

yesyes

no二、分析

其實這道題的思想就是並查集,就把輸入的兩個人的家族合在一起就行了。也就是用這樣乙個find函式來找「老祖宗」。

那麼,要怎樣來找他的老祖宗呢?我就是用乙個f陣列(father)來存他的老祖宗,然後輸入的兩個如果「老祖宗」不一樣的話,就把其中乙個人的老祖宗的老祖宗(原本是自己)改為另乙個。但這樣的話,在最後輸出的時候,就必須還要找一遍老祖宗才能正確的找到最終的根節點。舉個例子:

1的老祖宗是4;2的老祖宗是5.

那麼這個時候又輸入了 1 2;

所以這時把2的老祖宗5 的老祖宗由自己設為了4;

那麼這時 f[1]仍然是4,f[2]仍然是5;

如果在輸出時直接判斷f[1]是否等於f[2]時,會輸出no

綜上,我們發現,最後輸出時仍然需要在找一次老祖宗。

**如下:

#includeusing namespace std;

int f[5001],m,n,p,x,y;

int find(int x)

void o(int a,int b) //把其中乙個老祖宗的老祖宗設為另乙個老祖宗

int main()

for(int i=1;i<=p;i++)

}

親戚 並查集

若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。規定 x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。第一行 三個整數n,m,p,n 5000,m 5000,...

並查集(親戚)

include using namespace std int n int parent 100 void ufset 初始化 int find int x 返回第x節點所屬集合的根結點 return i void union int r1,int r2 將兩個不同集合的元素進行合併,使兩個集合中任...

並查集(親戚)

問題描述 若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。規定 x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。人數 5000,親戚關係 5000,詢問親戚關...