【CODECHEF】Children Trips
题意


题解
先看一下 https://www.cnblogs.com/yoyoball/p/9397857.html
这里说个坑点
在跳的时候,可能会遇到这种情况

假设求的是3->4,体力为2
3,4跳一次只能到2号点
所以加起来要两次,然而你发现只要一次就够了
所以在跳的时候只能跳到lca以下,然后看剩下的距离加起来要一次还是两次
代码
#include<algorithm>
#include<iostream>
#include<vector>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 100010
int dep[N],ans[N],up[N][21],up2[N][21],lev[N];
struct Query
{
int a,b,p,id;
}q[N];
struct line
{
int ed,cost;
};
vector<line> vec[N];
bool operator <(Query a,Query b)
{
return a.p<b.p;
}
int get_lca(int x,int y)
{
if(lev[x]<lev[y]) swap(x,y);
for(int i=20;lev[x]>lev[y];i--)
{
if(lev[up[x][i]]>=lev[y]) x=up[x][i];
}
if(x==y) return x;
for(int i=20;up[x][0]!=up[y][0];i--)
{
if(up[x][i]!=up[y][i])
{
x=up[x][i];
y=up[y][i];
}
}
return up[x][0];
}
int jump_once(int id,int p)
{
int ret=id;
for(int i=20;i>=0;i--)
{
if(dep[id]-dep[up[ret][i]]<=p) ret=up[ret][i];
}
return ret;
}
int jump(int a,int p,int lca,int &tot)//use by q[i].p>=len
{
if(a==lca) return a;
while(true)
{
int t=jump_once(a,p);
if(lev[t]>lev[lca]) a=t,tot++;
else return a;
}
}
int jump2(int a,int lca,int &tot)//use by q[i].p<len
{
if(a==lca) return a;
for(int i=20;i>=0;i--)
{
if(lev[up2[a][i]]>lev[lca])
a=up2[a][i],tot+=(1<<i);
}
return a;
}
void dfs(int id,int from,int p)
{
if(!p)
{
up[id][0]=from;
for(int i=1;i<=20;i++) up[id][i]=up[up[id][i-1]][i-1];
lev[id]=lev[from]+1;
}
else
{
up2[id][0]=jump_once(id,p);
for(int i=1;i<=20;i++) up2[id][i]=up2[up2[id][i-1]][i-1];
}
for(int i=0;i<vec[id].size();i++)
{
line l=vec[id][i];
if(l.ed==from) continue;
dep[l.ed]=dep[id]+l.cost;
dfs(l.ed,id,p);
}
}
int main()
{
int n,m,len;
cin>>n;
len=sqrt(n);
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
vec[a].push_back((line){b,c});
vec[b].push_back((line){a,c});
}
dfs(1,0,0);
cin>>m;
for(int i=1;i<=m;i++) scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].p),q[i].id=i;
sort(q+1,q+1+m);
for(int i=1;i<=m;i++)
{
int lca=get_lca(q[i].a,q[i].b);
if(q[i].p<len)
{
if(q[i].p!=q[i-1].p) dfs(1,0,q[i].p);
q[i].a=jump2(q[i].a,lca,ans[q[i].id]);
q[i].b=jump2(q[i].b,lca,ans[q[i].id]);
}
else
{
q[i].a=jump(q[i].a,q[i].p,lca,ans[q[i].id]);
q[i].b=jump(q[i].b,q[i].p,lca,ans[q[i].id]);
}
int dis=dep[q[i].a]+dep[q[i].b]-dep[lca]*2;
ans[q[i].id]+=(dis>q[i].p?2:1)-(dis==0);
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
看都看了,顺手点个推荐呗 :)

浙公网安备 33010602011771号