如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。
輸入格式:
第一行包含三個正整數n、m、s,分別表示樹的結點個數、詢問的個數和樹根結點的序號。
接下來n-1行每行包含兩個正整數x、y,表示x結點和y結點之間有一條直接連線的邊(資料保證可以構成樹)。
接下來m行每行包含兩個正整數a、b,表示詢問a結點和b結點的最近公共祖先。
輸出格式:
輸出包含m行,每行包含乙個正整數,依次為每乙個詢問的結果。
輸入樣例#1:
5 5 4輸出樣例#1:3 12 4
5 11 4
2 43 2
3 51 2
4 5
441時空限制:1000ms,128m44
資料規模:
對於30%的資料:n<=10,m<=10
對於70%的資料:n<=10000,m<=10000
對於100%的資料:n<=500000,m<=500000
樣例說明:
該樹結構如下:
第一次詢問:2、4的最近公共祖先,故為4。
第二次詢問:3、2的最近公共祖先,故為4。
第三次詢問:3、5的最近公共祖先,故為1。
第四次詢問:1、2的最近公共祖先,故為4。
第五次詢問:4、5的最近公共祖先,故為4。
故輸出依次為4、4、1、4、4。
模板題,不解釋了。
#include#includeview code#include
#include
using
namespace
std;
const
int maxn=500000+5
;inline
intread()
while(ch>='
0'&&ch<='9')
return x*f;
}int
n,m,s,num;
int f[maxn][20
],head[maxn],dep[maxn];
bool
vis[maxn];
struct
node
e[maxn
<<1
];inline
void add(int
from,int
to)inline
void dfs(int x,int
d) }
}inline
int lca(int a,int
b)
int d=dep[a]-dep[b];
for(int i=19;i>=0;i--)
if(d&(1
if(a==b) return
a;
for(int i=19;i>=0;i--)
if(f[a][i]!=f[b][i])
return f[a][0];}
intmain()
dfs(s,1);
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1
];
for(int i=1;i<=m;i++)
return0;
}
#include#includeview code#include
#include
using
namespace
std;
const
int maxn=500000+5
;inline
intread()
while(ch>='
0'&&ch<='9')
return x*f;
}int
n,m,s,num,qnum;
int father[maxn],head[maxn],qhead[maxn],a[maxn][3
];bool
vis[maxn];
struct
node
e[maxn
<<1
];struct
qnode
q[maxn
<<1
];inline
void add(int
from,int
to)inline
void qadd(int
from,int to,int
k)inline
int find(int
x)inline
void merge(int x,int
y)void tarjan(int
x)
for(int i=head[x];i;i=e[i].next)
}}int
main()
for(int i=1;i<=m;i++)
tarjan(s);
for(int i=1;i<=m;i++)
printf(
"%d\n
",a[i][2
]);
return0;
}
還有我補充一下我一直以來的思維誤區:
我原以為一棵樹的根節點變了,兩個節點的最近公共祖先是不會變的。
這是是錯誤的,反例很好舉:
假如兩個幾點的最近公共祖先是根節點,那麼當其中乙個節點變為根節點時,它們的最近公共祖先就變成了現在的根節點。
洛谷P3379 模板 最近公共祖先(LCA)
題目描述 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入輸出格式 輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩...
洛谷 P3379 模板 最近公共祖先(LCA)
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...
洛谷 P3379 最近公共祖先(LCA) 模板
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問a結點和b...