这个就比较简单了~
Code:
#include <cstdio> #include <algorithm> #define N 100004 #define inf 1000000000 #define setIO(s) freopen(s".in","r",stdin) // , freopen(s".out","w",stdout) using namespace std; int n,edges; int hd[N],to[N<<1],nex[N<<1],val[N<<1]; void add(int u,int v,int c) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; } namespace tree { int size[N],son[N],dep[N],dis[N],fa[N],top[N]; void dfs1(int u,int ff) { size[u]=1,fa[u]=ff; for(int i=hd[u];i;i=nex[i]) if(to[i]!=ff) { dis[to[i]]=dis[u]+val[i],dep[to[i]]=dep[u]+1; dfs1(to[i],u),size[u]+=size[to[i]]; if(size[to[i]]>size[son[u]]) son[u]=to[i]; } } void dfs2(int u,int tp) { top[u]=tp; if(son[u]) dfs2(son[u],tp); for(int i=hd[u];i;i=nex[i]) if(to[i]!=fa[u]&&to[i]!=son[u]) dfs2(to[i],to[i]); } int LCA(int x,int y) { while(top[x]!=top[y]) dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; return dep[x]<dep[y]?x:y; } int Dis(int x,int y) { return dis[x]+dis[y]-(dis[LCA(x,y)]<<1); } }; namespace seg { int tot; #define lson t[x].ls #define rson t[x].rs struct Node { int ls,rs,min; }t[N*100]; int newnode() { t[++tot].min=inf; return tot; } void pushup(int x) { t[x].min=inf; if(lson) t[x].min=min(t[x].min,t[lson].min); if(rson) t[x].min=min(t[x].min,t[rson].min); } void update(int &x,int l,int r,int p,int v) { if(!x) x=newnode(); if(l==r) { t[x].min=min(t[x].min,v); return; } int mid=(l+r)>>1; if(p<=mid) update(lson,l,mid,p,v); else update(rson,mid+1,r,p,v); pushup(x); } int query(int x,int l,int r,int L,int R) { if(!x) return inf; if(l>=L&&r<=R) return t[x].min; int mid=(l+r)>>1,re=inf; if(L<=mid) re=min(re,query(lson,l,mid,L,R)); if(R>mid) re=min(re,query(rson,mid+1,r,L,R)); return re; } #undef lson #undef rson }; int root,sn; int size[N],Fa[N],mx[N],vis[N],rt[N]; void getroot(int u,int ff) { size[u]=1,mx[u]=0; for(int i=hd[u];i;i=nex[i]) if(to[i]!=ff&&!vis[to[i]]) getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]); mx[u]=max(mx[u],sn-mx[u]); if(mx[u]<mx[root]) root=u; } void dfs(int u,int ff) { size[u]=1; for(int i=hd[u];i;i=nex[i]) if(to[i]!=ff&&!vis[to[i]]) dfs(to[i],u),size[u]+=size[to[i]]; } void calc(int u,int ff,int dep,int tp) { seg::update(rt[tp],1,n,u,dep); for(int i=hd[u];i;i=nex[i]) if(to[i]!=ff&&!vis[to[i]]) calc(to[i],u,dep+val[i],tp); } void prepare(int u) { vis[u]=1,calc(u,0,0,u); for(int i=hd[u];i;i=nex[i]) if(!vis[to[i]]) dfs(to[i],u),root=0,sn=size[to[i]],getroot(to[i],u),Fa[root]=u,prepare(root); } int query(int u,int l,int r) { int re=seg::query(rt[u],1,n,l,r),U=u; for(;Fa[u];u=Fa[u]) re=min(re, seg::query(rt[Fa[u]],1,n,l,r)+tree::Dis(U,Fa[u])); return re; } int main() { int i,j,m; // setIO("input"); scanf("%d",&n); for(i=1;i<n;++i) { int a,b,c; scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c); } tree::dfs1(1,0),tree::dfs2(1,1); root=0,mx[root]=sn=n,getroot(1,0),prepare(root); scanf("%d",&m); for(i=1;i<=m;++i) { int l,r,x; scanf("%d%d%d",&l,&r,&x); printf("%d ",query(x,l,r)); } return 0; }