祖孫詢問 (lca或dfs序 時間戳)

2022-08-20 12:48:11 字數 1840 閱讀 5712

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

提交: 13  解決: 6  難度:提高+/省選-

[提交] [狀態] [討論版] [命題人:xcgzjia]

題目描述

輸入輸出

樣例輸入 copy

10

234 -1

12 234

13 234

14 234

15 234

16 234

17 234

18 234

19 234

233 19

5234 233

233 12

233 13

233 15

233 19

樣例輸出 copy

100

02

提示

思路:方法1

很明顯是一道求lca的題

求出lca判斷就可以了

1 #include2

using

namespace

std;

3const

int mssc=4e4+5;4

intn,m;

5int d[mssc],f[mssc][20

];6 vectorg[mssc];

7void pre(int u,int fa)

12int sz=g[u].size();//

表示u所連線的邊數

13for(int i=0;i)18}

19}20int lca(int x,int

y)24

for(int i=15;i>=0;i--)

28if(x==y)31}

32for(int i=15;i>=0;i--)37}

38return f[x][0];//

答案就是x的父節點 39}

40int

main()else52}

53 pre(root,0

);54 scanf("

%d",&m);

55for(int i=1;i<=m;i++)else

if(t==b&&a!=t)else65}

66return0;

67 }

方法2求出給定樹的dfs序

觀察可以發現,如果存在x,y有祖孫關係,那麼無非就有兩種情況:

第一種是x在y的區間內

第二種就是y在x的區間內

那麼我們只要求出x和y進入dfs的時間和離開的時間檢視他們的包含情況就可以了

也就是說 求出這棵樹所有點dfs序的時間戳 問詢的時候判斷一下即可

1 #include2

using

namespace

std;

3const

int maxn=400005;4

intlen,n,m,tim;

5int

st[maxn],et[maxn];

6int

pos[maxn];

7 vectorg[maxn];

8void dfs(int u,int

fa)16

}17 et[pos[u]]=++tim;18}

19int

main()else30}

31 dfs(root,0

);32 scanf("

%d",&m);

33for(int i=1;i<=m;i++)else

if(st[a]>st[b]&&st[a]et[a])else44}

45return0;

46 }

AcWing 1172 祖孫詢問(lca)

給定一棵包含 n 個節點的有根無向樹,節點編號互不相同,但不一定是 1 n。有 m 個詢問,每個詢問給出了一對節點的編號 x 和 y,詢問 x 與 y 的祖孫關係。輸入第一行包括乙個整數 表示節點個數 接下來 n 行每行一對整數 a 和 b,表示 a 和 b 之間有一條無向邊。如果 b 是 1,那麼...

祖孫詢問 紀中3054 lca

已知一棵n個節點的有根樹。有m個詢問。每個詢問給出了一對節點的編號x和y,詢問x與y的祖孫關係。輸入第一行包括乙個整數n表示節點個數。接下來n行每行一對整數對a和b表示a和b之間有連邊。如果b是 1,那麼a就是樹的根。第n 2行是乙個整數m表示詢問個數。接下來m行,每行兩個正整數x和y。對於每乙個詢...

JZ3054祖孫詢問

題目 已知一棵n個節點的有根樹。有m個詢問。每個詢問給出了一對節點的編號x和y,詢問x與y的祖孫關係。分析 dfs序以及各種求lca演算法均可秒殺此題。dfs遍歷樹,記錄每個點x的第一次訪問時間st x 和最後一次訪問時間ed x 若y在以x為根的子樹中,則一定有st x 附上 const maxn...