題目:
已知一棵n個節點的有根樹。有m個詢問。每個詢問給出了一對節點的編號x和y,詢問x與y的祖孫關係。
分析:
dfs序以及各種求lca演算法均可秒殺此題。
dfs遍歷樹,記錄每個點x的第一次訪問時間st[x]和最後一次訪問時間ed[x],若y在以x為根的子樹中,則一定有st[x]。
附上**:
const
maxn=40000;
type
arr=record
y,next:longint;
end;
varn,m,test,temp:longint;
a,b:array [0..maxn] of longint;
cristine:array [0..maxn,0..20] of longint;
elist:array [0..maxn*2] of arr;
procedure add(x1,y1:longint);
begin
inc(test);
with elist[test] do
begin
y:=y1;
next:=a[x1];
a[x1]:=test;
end;
inc(test);
with elist[test] do
begin
y:=x1;
next:=a[y1];
a[y1]:=test;
end;
end;
procedure init;
vari,x,y:longint;
begin
test:=0;
readln(n);
for i:=1 to n do
begin
readln(x,y);
if y=-1 then
temp:=x
else add(x,y);
end;
end;
procedure dfs(x:longint);
vari:longint;
begin
for i:=1 to 15 do
begin
if b[x]<(1 shl i) then
break;
cristine[x,i]:=cristine[cristine[x,i-1],i-1];
end;
i:=a[x];
while i>0 do
with elist[i] do
begin
if y<>cristine[x,0] then
begin
b[y]:=b[x]+1;
cristine[y,0]:=x;
dfs(y);
end;
i:=next;
end;
end;
function lca(x,y:longint):longint;
vart,i:longint;
begin
if b[x]0 then
x:=cristine[x,i];
for i:=15 downto 0 do
if cristine[x,i]<>cristine[y,i] then
begin
x:=cristine[x,i];
y:=cristine[y,i];
end;
if x=y then
exit(x);
exit(cristine[x,0]);
end;
procedure main;
vari,x,y,t:longint;
begin
dfs(temp);
readln(m);
for i:=1 to m do
begin
readln(x,y);
if x=y then
writeln('0')
else
begin
t:=lca(x,y);
if t=x then
writeln('1')
else
if t=y then
writeln('2')
else
writeln('0');
end;
end;
end;
begin
init;
main;
end.
祖孫詢問 紀中3054 lca
已知一棵n個節點的有根樹。有m個詢問。每個詢問給出了一對節點的編號x和y,詢問x與y的祖孫關係。輸入第一行包括乙個整數n表示節點個數。接下來n行每行一對整數對a和b表示a和b之間有連邊。如果b是 1,那麼a就是樹的根。第n 2行是乙個整數m表示詢問個數。接下來m行,每行兩個正整數x和y。對於每乙個詢...
CQYZ OJ Contest 133 祖孫詢問
同步 已知一顆有根樹。有m個詢問。每個詢問給出了一對節點x,y,輸出x,y的祖孫關係 第一行節點數目n接下來n行,每行一對整數a,b,表示a和b之間有邊。如果b 1,那麼a就是數根接下來是乙個整數m,表示詢問的個數接下來m行,每行兩個正整數x,y 對於每乙個詢問,如果x是y的祖先,輸出1 如果y是x...
最近公共祖先 祖孫詢問
給定一棵包含 nn 個節點的有根無向樹,節點編號互不相同,但不一定是 1 n1 n 有 mm 個詢問,每個詢問給出了一對節點的編號 xx 和 yy 詢問 xx 與 yy 的祖孫關係。輸入格式輸入第一行包括乙個整數 表示節點個數 接下來 nn 行每行一對整數 aa 和 bb 表示 aa 和 bb 之間...