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;
}
#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模板
- 洛谷.4180.[模板]次小生成树Tree(Kruskal LCA 倍增)
- {模板}LCA倍增
- LCA离线模板(Tarjan)倍增模板 hdu2586
- 倍增LCA模板
- 【 lca倍增模板】
- lca(最近公共祖先)倍增模板【pascal】
- 【模板】倍增LCA
- 求LCA最近公共祖先的在线倍增算法模板_C++
- HDU2586 How far away ?(LCA模板题)
- HDU-2586-How far away ?(倍增求LCA模板)
- LCA Tarjan及倍增模板(POJ 1330)
- LCA Tarjan模板 HDU2586
- [模板] - LCA倍增
- POJ 1330 LCA倍增模板题
- 倍增法求lca 模板
- czl蒟蒻的模板库6——倍增LCA
- 洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan)
- poj1330 lca倍增算法模板
- 【模板】【LCA】【树上倍增】