洛谷 P3379 【模板】最近公共祖先(LCA)
2017-09-06 21:23
507 查看
模板题嘛不多说,直接上代码
用前向星存哦.....
然后记得register优化 开氧气啦
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define maxn 1000010
using namespace std;
int next[maxn],st[maxn],to[maxn],dep[maxn],n,m,root,topt,f[maxn][20],lg[maxn];
int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getcha
4000
r();
while (c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x;
} //快读x记得赋出值0
void add(int x,int y)
{
to[++topt]=y;
next[topt]=st[x];
st[x]=topt;
} //前向星存233
void build_tree(int x)
{
int p=st[x];
while (to[p]!=0)
{
if (!dep[to[p]])
{
dep[to[p]]=dep[x]+1;
f[to[p]][0]=x;
build_tree(to[p]);
}
p=next[p]; //注意!此处写挂2次
}
} //图转树
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
while (dep[x]>dep[y]) x=f[x][lg[dep[x]-dep[y]]];
if (x==y) return x;
for (register int i=lg[dep[x]];i>=0;i--)
if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
} //lca板子
void init()
{
for (register int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i-1]+1 == i);
for (register int j=1;j<=19;j++)
for (register int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
} //千万别忘了预处理!!
int main()
{
n=read(); m=read(); root=read();
for (register int i=1;i<=n-1;i++)
{
int fr,to; fr=read(); to=read();
add(fr,to); add(to,fr);
}
dep[root]=1;
build_tree(root);
init();
for (register int i=1;i<=m;i++)
{
int a,b; a=read(); b=read();
printf("%d\n",lca(a,b));
}
return 0;
}
用前向星存哦.....
然后记得register优化 开氧气啦
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define maxn 1000010
using namespace std;
int next[maxn],st[maxn],to[maxn],dep[maxn],n,m,root,topt,f[maxn][20],lg[maxn];
int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getcha
4000
r();
while (c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x;
} //快读x记得赋出值0
void add(int x,int y)
{
to[++topt]=y;
next[topt]=st[x];
st[x]=topt;
} //前向星存233
void build_tree(int x)
{
int p=st[x];
while (to[p]!=0)
{
if (!dep[to[p]])
{
dep[to[p]]=dep[x]+1;
f[to[p]][0]=x;
build_tree(to[p]);
}
p=next[p]; //注意!此处写挂2次
}
} //图转树
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
while (dep[x]>dep[y]) x=f[x][lg[dep[x]-dep[y]]];
if (x==y) return x;
for (register int i=lg[dep[x]];i>=0;i--)
if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
} //lca板子
void init()
{
for (register int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i-1]+1 == i);
for (register int j=1;j<=19;j++)
for (register int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
} //千万别忘了预处理!!
int main()
{
n=read(); m=read(); root=read();
for (register int i=1;i<=n-1;i++)
{
int fr,to; fr=read(); to=read();
add(fr,to); add(to,fr);
}
dep[root]=1;
build_tree(root);
init();
for (register int i=1;i<=m;i++)
{
int a,b; a=read(); b=read();
printf("%d\n",lca(a,b));
}
return 0;
}
相关文章推荐
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 洛谷——P3379 【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- 【洛谷】3379 【模板】最近公共祖先(LCA)
- 洛谷 P 3379 【模板】最近公共祖先(LCA)
- 洛谷3379 【模板】最近公共祖先(LCA)
- 洛谷 3379_【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- 洛谷 P 3379 【模板】最近公共祖先(LCA)
- 4000 【模板】最近公共祖先(LCA)
- 洛谷3379 最近公共祖先模板(倍增)
- P3379最近公共祖先(LCA)
- [模板]最近公共祖先LCA
- AC日记——【模板】最近公共祖先(LCA)洛谷 P3379
- 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)
- LCA(最近公共祖先)倍增法模板及总结
- 模板_LCA(最近公共祖先)
- 【模板】lca 最近公共祖先