【CODECHEF】Children Trips
题意
题解
先看一下
这里说个坑点
在跳的时候,可能会遇到这种情况
假设求的是3->4,体力为2
3,4跳一次只能到2号点
所以加起来要两次,然而你发现只要一次就够了
所以在跳的时候只能跳到lca以下,然后看剩下的距离加起来要一次还是两次
代码
#include#include #include #include #include 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 vec[N]; bool operator <(Query a,Query b) { return a.p 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 =0;i--) { if(lev[up2[a][i]]>lev[lca]) a=up2[a][i],tot+=(1<>n; len=sqrt(n); for(int i=1;i >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 q[i].p?2:1)-(dis==0); } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); }