日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

wikioi-天梯-进入省队-并查集-1073:家族

發布時間:2023/12/20 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wikioi-天梯-进入省队-并查集-1073:家族 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述 Description

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

輸入描述 Input Description

第一行:三個整數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是否具有親戚關系。

輸出描述 Output Description

P行,每行一個’Yes’或’No’。表示第i個詢問的答案為“具有”或“不具有”親戚關系。

樣例輸入 Sample Input

6 5 3

1 2

1 5

3 4

5 2

1 3

1 4

2 3

5 6

樣例輸出 Sample Output

Yes

Yes

No

數據范圍及提示 Data Size & Hint

n<=5000,m<=5000,p<=5000

類型:圖論? 難度:1.5

題意:給出n個點的m個等價類關系(給出a b表示ab屬于同一個集合,具有傳遞性和可逆性),給出p個詢問,每個查詢輸出兩個數是否在一個集合中。

分析:典型的并查集問題,即初始時,將n個數看成n個集合,每次給出a,b時,合并ab所在的兩個集合。

用樹存儲集合,fa[i]表示點i的父節點,初始化fa[i]=i,每次合并i,j所在的集合時,分別找到i,j所在樹的根節點,如x,y,然后 fa[x]=y。

查詢i,j所在集合時,找到i,j所在樹的根節點,比較是否相同。

關于上述算法,有兩個經典優化方法:

1、每次查詢時,將查詢點到根節點路徑上的所有點的父節點置為根節點,降低樹的高度,方便下次查詢。

2、合并集合時,將高度低的樹合并到高的樹中,如height(a)>height(b),那么father[b] = a。

注意:看了大部分人的代碼,沒有做2這個優化。我估計原因是由于在合并操作中,會調用查詢操作(先要查詢需合并兩個點的根節點才能合并,我也在這犯了一個錯誤),而查詢操作已經做了1的優化,第2個優化就有點多余了(做了1的優化,樹的高度也不好記錄了),所以在實際實現中,第2個優化用的較少。

代碼:

#include<iostream> #include<cstdio> using namespace std;int n,m,p; int fa[5010];int mfind(int a) {if(fa[a] != a) fa[a] = mfind(fa[a]);return fa[a]; }void mmerge(int a,int b) {fa[mfind(a)] = mfind(b); }int main() {scanf("%d%d%d",&n,&m,&p);for(int i=1; i<=n; i++)fa[i] = i;int a,b;while(m--){scanf("%d%d",&a,&b);mmerge(a,b);}while(p--){scanf("%d%d",&a,&b);if(mfind(a) == mfind(b))printf("Yes\n");else printf("No\n");} }


?

總結

以上是生活随笔為你收集整理的wikioi-天梯-进入省队-并查集-1073:家族的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。