時間限制: 1 sec 記憶體限制: 128 mb
提交: 13 解決: 6 難度:提高+/省選-
[提交] [狀態] [討論版] [命題人:xcgzjia]
題目描述
輸入輸出
樣例輸入 copy
10樣例輸出 copy234 -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
100提示02
思路:方法1
很明顯是一道求lca的題
求出lca判斷就可以了
1 #include2方法2求出給定樹的dfs序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 }
觀察可以發現,如果存在x,y有祖孫關係,那麼無非就有兩種情況:
第一種是x在y的區間內
第二種就是y在x的區間內
那麼我們只要求出x和y進入dfs的時間和離開的時間檢視他們的包含情況就可以了
也就是說 求出這棵樹所有點dfs序的時間戳 問詢的時候判斷一下即可
1 #include2using
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...