您的位置:首页 > 其它

HDU 2586 How far away ?(LCA在线算法实现)

2017-08-06 15:45 260 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:
给出一棵树,求出树上任意两点之间的距离。

思路:

这道题可以利用LCA来做,记录好每个点距离根结点的距离,然后只要计算出两点的LCA,这样一来答案就是distance[u]+distance[v]-2distance[LCA]。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=40000+5;

int n, m;
int num;
int tot;
int head[maxn];
int vis[maxn];
int ver[2*maxn];
int deep[2*maxn];
int dir[maxn];
int first[maxn];
int dp[2*maxn][25];

struct node
{
int v,w;
int next;
}e[2*maxn];

void addEdge(int u, int v, int w)
{
e[num].v=v;
e[num].w=w;
e[num].next=head[u];
head[u]=num++;
}

void dfs(int u, int dep)
{
vis[u]=1;
ver[++tot]=u;   //遍历序列
first[u]=tot;   //结点第一次出现位置
deep[tot]=dep;     //深度
for(int i=head[u];i!=-1;i=e[i].next)
{
if(!vis[e[i].v])
{
int v=e[i].v, w=e[i].w;
dir[v]=dir[u]+w;   //距离
dfs(v,dep+1);
ver[++tot]=u;      //回溯
deep[tot]=dep;
}
}
}

void ST(int n)
{
for(int i=1;i<=n;i++)  dp[i][0]=i;
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
dp[i][j]=deep[a]<deep[b]?a:b;
}
}

int RMQ(int L, int R)
{
int k=0;
while((1<<(k+1))<=R-L+1)  k++;
int a=dp[L][k], b=dp[R-(1<<k)+1][k];
return deep[a]<deep[b]?a:b;
}

int LCA(int u, int v)
{
int x=first[u], y=first[v];   //查找出他最先出现的地方
if(x>y)  swap(x,y);
int res=RMQ(x,y);    //查询出的是他祖先的下标
return ver[res];
}

int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
num=0; tot=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
}
dir[1]=0;
dfs(1,1);
ST(2*n-1);
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
int lca=LCA(u,v);
printf("%d\n",dir[u]+dir[v]-2*dir[lca]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: