给出一棵树
询问 a-b的路径长度是多少
给出一棵树
询问 a-b的路径长度是多少
dist【i】记录节点i到根的距离长度
对于每次询问,用RMQ预处理的LCA可以在线回答每个询问, ans=dist[a]+dist[b]-2*dist[LCA(a,b)];
Source Code
Problem: 1986 User: 1013101127
Memory: 18576K Time: 1469MS
Language: G++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=40001;
const int maxm=1000002;
struct Node
{
int v,len;
};
vector<Node>mp[maxm];
struct QUE
{
int u;
int v;
int id;
};
vector<QUE>Q[maxn];
int n,m;
int tmp;
int dfn[maxn];
int vis[maxn];
int fa[maxn];
int dist[maxn];
int flag[maxn];
int lca[maxn];
int ans[maxn];
void init()
{
tmp=1;
for(int i=1;i<=n;i++)
mp[i].clear();
for(int i=1;i<=n;i++)
Q[i].clear();
memset(vis,0,sizeof(vis));
memset(flag,0,sizeof(flag));
}
int findx(int x)
{
if(fa[x]==x)
return x;
else
return findx(fa[x]);
}
void Union(int a,int b)
{
int x = findx(a);
int y = findx(b);
fa[x] = y;
}
void tarjan(int u,int dance)
{
vis[u]=1;
lca[u]=u;
fa[u]=u;
dist[u]=dance;
for(int i=0;i<mp[u].size();i++)
{
int vv=mp[u][i].v;
if(!vis[vv])
{
tarjan(vv,dance+mp[u][i].len);
Union(u,vv);
lca[findx(u)]=u;
}
}
flag[u]=1;
for(int i=0;i<Q[u].size();i++)
{
int v1=Q[u][i].v;
if(flag[v1])
{
ans[Q[u][i].id]=dist[u]+dist[v1]-2*dist[lca[findx(v1)]];
}
}
}
int main()
{
int uu,vv,ll;
char ch;
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&uu,&vv,&ll);
cin>>ch;
Node one;
one.v=vv;
one.len=ll;
mp[uu].push_back(one);
one.v=uu;
one.len=ll;
mp[vv].push_back(one);
}
int cas;
scanf("%d",&cas);
for(int i=0;i<cas;i++)
{
scanf("%d%d",&uu,&vv);
QUE qe;
qe.u=uu;
qe.v=vv;
qe.id=i;
Q[uu].push_back(qe);
qe.id=i;
qe.u=vv;
qe.v=uu;
Q[vv].push_back(qe);
}
tarjan(1,0);
for(int i=0;i<cas;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}