在线 RMQ
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int n;
int vis[40010],id[40010],depth[40010*2],vs[40010*2],ans[40010];
int dp[40010*2][30];
struct node1
{
int b,c;
};
vector<node1> vec[40010],node[40010];
void rmq_init(int len)
{
for(int i=0;i<=len;i++)
dp[i][0]=i;
for(int j=1;(1<<j)<=len;j++)
for(int i=1;i+(1<<j)-1<=len;i++)
{
int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
dp[i][j]=depth[a]<depth[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 depth[a]<depth[b]?a:b;
}
int lca(int u,int v)
{
int x=id[u];
int y=id[v];
if(x>y)
swap(x,y);
return vs[rmq(x,y)];
}
void dfs(int v,int p,int d,int &k)
{
id[v]=k;
vs[k]=v;
depth[k++]=d;
for(int i=0;i<vec[v].size();i++)
{
node1 pp=vec[v][i];
if(pp.b!=p)
{
ans[pp.b]=ans[v]+pp.c;
dfs(pp.b,v,d+1,k);
vs[k]=v;
depth[k++]=d;
}
}
}
void init(int x)
{
int k=0;
dfs(x,-1,0,k);
rmq_init(n*2-1);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
int q,nn;
scanf("%d%d",&n,&q);
nn=n-1;
int a,b,c;
while(nn--)
{
scanf("%d%d%d",&a,&b,&c);
node1 p1,p2;
p1.b=b,p1.c=c;
p2.b=a,p2.c=c;
vec[a].push_back(p1);
vec[b].push_back(p2);
vis[b]=1;
}
int keep;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
keep=i;
break;
}
}
ans[keep]=0;
init(keep);
for(int i=0;i<q;i++)
{
scanf("%d%d",&a,&b);
int v=lca(a,b);
printf("%d\n",ans[a]+ans[b]-2*ans[v]);
}
}
return 0;
}
离线 targin
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int n;
int pre[40010],rankk[40010],vis[40010],ans[40010],dis[40010];
vector<int>num[40010],w[40010],vec[40010],node[40010];
void init()
{
for(int i=0;i<=n;i++)
{
vec[i].clear();
node[i].clear();
num[i].clear();
w[i].clear();
vis[i]=0;
pre[i]=i;
rankk[i]=1;
ans[i]=0;
dis[i]=0;
}
}
int findd(int x)
{
if(x==pre[x])
return x;
return findd(pre[x]);
}
void unite(int a,int b)
{
a=findd(a);
b=findd(b);
if(a==b)
return;
pre[b]=a;
}
void dfs(int x,int val)
{
vis[x]=1;
dis[x]=val;
for(int i=0;i<vec[x].size();i++)
{
int v=vec[x][i];
if(vis[v])
continue;
dfs(v,val+w[x][i]);
unite(x,v);
}
for(int i=0;i<node[x].size();i++)
{
int v=node[x][i];
if(vis[v])
{
ans[num[x][i]]=dis[x]+dis[v]-2*dis[findd(v)];
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int q,nn;
scanf("%d%d",&n,&q);
init();
nn=n-1;
int a,b,c;
while(nn--)
{
scanf("%d%d%d",&a,&b,&c);
vec[a].push_back(b);
vec[b].push_back(a);
w[a].push_back(c);
w[b].push_back(c);
}
for(int i=0;i<q;i++)
{
scanf("%d%d",&a,&b);
node[a].push_back(b);
node[b].push_back(a);
num[a].push_back(i);
num[b].push_back(i);
}
dfs(1,0);
for(int i=0;i<q;i++)
printf("%d\n",ans[i]);
}
return 0;
}
在线 倍增
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int n;
int vis[40010],depth[40010],pre[30][40010],ans[40010];
struct node1
{
int b,c;
};
vector<node1> vec[40010];
void dfs(int u,int fa,int d)
{
pre[0][u]=fa;
depth[u]=d;
for(int i=0;i<vec[u].size();i++)
{
node1 v=vec[u][i];
if(v.b!=fa)
{
ans[v.b]=ans[u]+v.c;
dfs(v.b,u,d+1);
}
}
}
void init(int x)
{
dfs(x,-1,0);
for(int k=0;(1<<(k+1))<n;k++)
{
for(int v=0;v<n;v++)
{
if(pre[k][v]<0)
pre[k+1][v]=-1;
else
pre[k+1][v]=pre[k][pre[k][v]];
}
}
}
int lca(int u,int v)
{
int t=0;
while((1<<t)<=n)
t++;
if(depth[u]>depth[v])
swap(u,v);
for(int k=0;k<t;k++)
{
if((depth[v]-depth[u])>>k&1)
v=pre[k][v];
}
if(u==v)
return u;
for(int k=t-1;k>=0;k--)
{
if(pre[k][u]!=pre[k][v])
{
u=pre[k][u];
v=pre[k][v];
}
}
return pre[0][u];
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
int q,nn;
scanf("%d%d",&n,&q);
nn=n-1;
int a,b,c;
while(nn--)
{
scanf("%d%d%d",&a,&b,&c);
node1 p1,p2;
p1.b=b,p1.c=c;
p2.b=a,p2.c=c;
vec[a].push_back(p1);
vec[b].push_back(p2);
vis[b]=1;
}
int keep;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
keep=i;
break;
}
}
ans[keep]=0;
init(keep);
for(int i=0;i<q;i++)
{
scanf("%d%d",&a,&b);
int v=lca(a,b);
printf("%d\n",ans[a]+ans[b]-2*ans[v]);
}
}
return 0;
}