您的位置:首页 > 其它

【 lca倍增模板】

2017-06-15 21:41 176 查看

题目描述

对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值

输入

第一行 n,表示结点个数,接下来 n-1 行,每行 a b w 表示 a 与 b 之间有一条权值为 w的双向边
第 n+1 行:m 表示询问的个数,接下来 m 行,每行一个询问 a 和 b

输出

对于每个询问,输出两个结点的路径上边权的最小值

样例输入

10 1 4 11161 3 8 7244 5 9 635 1 10 23999 10 6 23998 7 5 16083 4 3 7145 1 7 20425 3 2 25701 14 1 5 9 3 3 1 7 5 9 1 5 1 1 7 3 1 1 8 1 3 7 6 5 7 7 1 1 7

样例输出

16083 635 7145 16083 635 16083 20425 7145 7145 7145 20425 16083 20425 20425

题解:
发个模版,坑爹数据,dfs栈溢出,于是改成bfs

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=100005,INF=1999999999;
int head
,num=1;
struct Lin
{
int next,to,dis;
}a[N<<1];
void init(int x,int y,int z)
{
a[++num].next=head[x];
a[num].to=y;
a[num].dis=z;
head[x]=num;
}
int gi(){
int str=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
return str*f;
}
int n,fa
[21],dis
[21],dep
,q
;
void bfs()
{
dep[1]=1;
int t=0,sum=1,x,u;
q[1]=1;
while(t!=sum)
{
x=q[++t];
for(int i=head[x];i;i=a[i].next)
{
u=a[i].to;
if(dep[u])continue;
q[++sum]=u;dep[u]=dep[x]+1;
dis[u][0]=a[i].dis;fa[u][0]=x;
}
}
}
int maxdep;
void prework()
{
for(int j=1;j<=maxdep;j++)
for(int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
for(int j=1;j<=maxdep;j++)
for(int i=1;i<=n;i++)
dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]);
}
void Clear()
{
for(int j=0;j<=maxdep;j++)
for(int i=1;i<=n;i++)dis[i][j]=INF;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int deep=dep[x]-dep[y];
int ans=INF;
for(int i=maxdep;i>=0;i--)
{
if(deep&(1<<i))
{
if(dis[x][i]<ans)ans=dis[x][i];
x=fa[x][i];
}
}
if(x==y)return ans;
for(int i=maxdep;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])
{
if(dis[x][i]<ans)ans=dis[x][i];
if(dis[y][i]<ans)ans=dis[y][i];
x=fa[x][i];y=fa[y][i];
}
}
return min(ans,min(dis[x][0],dis[y][0]));
}
int main()
{
n=gi();
maxdep=log(n)/log(2)+1;
int x,y,z;
Clear();
int ca;
for(int i=1;i<n;i++)
{
x=gi();y=gi();z=gi();
init(x,y,z);init(y,x,z);
}
bfs();
prework();
int m=gi();
while(m--)
{
x=gi();y=gi();
ca=lca(x,y);
printf("%d\n",lca(x,y));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: