很久没有碰竞赛了,手生……
为学习焦头烂额,抽不出时间,还是学习方法真的有问题?都高二下期了,该怎么办才好
好吧好吧,给自己打鸡血,加油加油加油啊!!!!
热血模板复习之旅开启,叮~
链式前向星:
用来存图、遍历图之类的
倍增求最近公共祖先:
需要一个father数组、deep深度数组
一个dfs函数处理deep深度数组、father数组,一个find_lca函数来找祖先
// 10130
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define M 200006
#define N 100005
#define LL long long
using namespace std;
inline int wread (){
char c(getchar ());int wans (0),flag(1);
while (c<'0' || c>'9'){if (c=='-') flag=-1;c=getchar ();}
while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();}
return wans*=flag;
}
int n;
int K,hed[N];
struct node {int v,nxt;}e[M];//e[i]表示边序号为i的边的信息
void ad (int u,int v){//hed[u]以u节点为起点的上一条边的边序号
e[++K].v=v;e[K].nxt=hed[u];hed[u]=K;
}//有的只需要存终点信息即可
//最后的遍历顺序与输入相反
int p[N][23],dep[N];
void dfs (int x,int fa){
p[x][0]=fa;
for (int i(1);i<=20;++i) p[x][i]=p[p[x][i-1]][i-1];
for (int i(hed[x]);i;i=e[i].nxt){
int v(e[i].v);
if (v==fa) continue;
dep[v]=dep[x]+1;
dfs (v,x);
}
}
inline int fnd_lca (int a,int b){
if (dep[a]>dep[b]) swap (a,b);
for (int i(20);i>=0;--i)
if (dep[p[b][i]]>=dep[a]) b=p[b][i];
if (a==b) return a;
for (int i(20);i>=0;--i){
if (p[a][i] == p[b][i]) continue;
a=p[a][i];b=p[b][i];
}
return p[a][0];
}
int main (){
// freopen (")
n=wread();
for (int i(1);i<n;++i){
int x(wread()),y(wread());
ad (x,y);ad(y,x);
}
dfs (1,1);//写-1不可以!
// for (int i(1);i<=n;++i){
// printf("%d ",dep[i]);
// }puts ("");
// for (int i(1);i<=n;++i){
// printf("%d ",p[i][0]);
// }puts ("");
int Q(wread());
while (Q--){
int x(wread()),y(wread());
int ans_lca(fnd_lca(x,y));
// printf("%d \n",ans_lca);
printf("%lld\n",(LL)dep[x]+(LL)dep[y]-(LL)(dep[ans_lca]<<1));
}
return 0;
}
未完待续。。。