您的位置:首页 > 其它

hdu2586 倍增lca模板

2017-11-27 19:09 211 查看
树上给出两个点,求两点的最短距离

#include <iostream>

using namespace std;

#include <queue>

#include <string.h>

#include <string>

struct edges

{
int x,y,v;
int next;

}edge[100005];

int head[100005],num;

int p[50005][20],pow=18,d[50005],s[50005][20];

void add_edge(int x,int y,int v)

{
edge[num].x=x;
edge[num].y=y;
edge[num].v=v;
edge[num].next=head[x];
head[x]=num++;

}

void dfs(int pre,int now,int v)

{
int i;
d[now]=d[pre]+1;
p[now][0]=pre;
s[now][0]=v;
for(i=1;i<pow;i++)
{
p[now][i]=p[p[now][i-1]][i-1];
s[now][i]=s[now][i-1]+s[p[now][i-1]][i-1];
}
i=head[now];
while(i)
{
if(edge[i].y!=pre)
dfs(now,edge[i].y,edge[i].v);
i=edge[i].next;
}

}

int solve(int a,int b)

{
int i,j,sum=0;
if(d[a]<d[b])  a^=b , b^=a ,a^=b;
j=d[a]-d[b];
for(i=0;i<pow;i++)
if( (1<<i)&j ) sum+=s[a][i] , a=p[a][i];

if(a!=b)
{
for(i=pow-1;i>=0;i--)
if(p[a][i]!=p[b][i]) 
{
sum+=s[a][i]+s[b][i]; 
a=p[a][i] , b=p[b][i];
}
sum+=s[a][0]+s[b][0];
}
return sum;

}

void init()

{
memset(p,0,sizeof(p));
memset(head,0,sizeof(head));
memset(s,0,sizeof(s));
d[1]=1;
num=1;

}

int main()

{
int t,x,y,i,j,n,q;
cin>>t;
while(t--)
{
init();
cin>>n>>q;
for(i=1;i<n;i++)
{
cin>>x>>y>>j;
add_edge(x,y,j);
add_edge(y,x,j);
}
dfs(0,1,0);
while(q--)
{
cin>>x>>y;
cout<<solve(x,y)<<endl;
}
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lca模板 hdu