1
3
1 2 7
2 3 5
4
3 10
3 7
3 6
3 4
7
7
5
-1
Hint
2<=n<=10^5 2<=Q<=10^5 1<=W,Y<=10^9 The data is guaranteed that your program will overflow if you use recursion.
分析:首先把边的权值从小到达排列,然后把询问的y值也从小到达排列,然后对于每一个询问,把小于y值的边更新到线段树中,接着求出该次询问的最大值,把答案记录到原来顺序的数组里面,最后输出即可;
程序:
#pragma comment(linker, "/STACK:102400000,102400000")
#include"stdio.h"
#include"string.h"
#include"iostream"
#include"map"
#include"string"
#include"queue"
#include"stdlib.h"
#include"math.h"
#define M 100009
#define inf 100000000
using namespace std;
struct node
{
int u,v,next;
}edge[M*2];
int t,head[M],son[M],fa[M],num[M],p[M],fp[M],deep[M],cnt[M],pos,top[M],Max;
void init()
{
t=pos=0;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
}
void add(int u,int v)
{
edge[t].u=u;
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void dfs(int u,int f,int d)
{
deep[u]=d;
fa[u]=f;
num[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=f)
{
dfs(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[son[u]]<num[v])
son[u]=v;
}
}
}
void getpos(int u,int sp)
{
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)return;
getpos(son[u],sp);
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=fa[u]&&v!=son[u])
getpos(v,v);
}
}
struct Node
{
int l,r,maxi;
}tree[M*5];
void pushup(int i)
{
tree[i].maxi=max(tree[i*2].maxi,tree[i*2+1].maxi);
}
void make(int l,int r,int i)
{
tree[i].l=l;
tree[i].r=r;
if(l==r)
{
tree[i].maxi=-inf;
return;
}
int mid=(l+r)/2;
make(l,mid,i*2);
make(mid+1,r,i*2+1);
pushup(i);
}
void updata(int p,int q,int i)
{
if(tree[i].r==p&&tree[i].l==p)
{
tree[i].maxi=q;
return;
}
int mid=(tree[i].l+tree[i].r)/2;
if(p<=mid)
updata(p,q,i*2);
else
updata(p,q,i*2+1);
pushup(i);
}
void query(int l,int r,int i)
{
if(tree[i].l==l&&tree[i].r==r)
{
Max=max(Max,tree[i].maxi);
return;
}
int mid=(tree[i].r+tree[i].l)/2;
if(r<=mid)
query(l,r,i*2);
else if(l>mid)
query(l,r,i*2+1);
else
{
query(l,mid,i*2);
query(mid+1,r,i*2+1);
}
pushup(i);
}
int findmax(int u,int v)
{
int f1=top[u];
int f2=top[v];
int ans=-inf;
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1,f2);
swap(u,v);
}
Max=-inf;
query(p[f1],p[u],1);
ans=max(ans,Max);
u=fa[f1];
f1=top[u];
}
if(v==u)
return ans;
if(deep[u]>deep[v])
swap(u,v);
Max=-inf;
query(p[son[u]],p[v],1);
ans=max(ans,Max);
return ans;
}
struct Edge
{
int u,v,w,x,y,kk;
}e[M],Q[M];
int cmp(const void *a,const void *b)
{
return (*(struct Edge*)a).w-(*(struct Edge*)b).w;
}
int cmpy(const void *a,const void *b)
{
return (*(struct Edge*)a).y-(*(struct Edge*)b).y;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n,i;
init();
scanf("%d",&n);
for(i=0;i<n-1;i++)
{
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
add(e[i].u,e[i].v);
add(e[i].v,e[i].u);
}
dfs(1,1,0);
getpos(1,1);
make(1,pos-1,1);
qsort(e,n-1,sizeof(e[0]),cmp);
int que;
scanf("%d",&que);
for(i=0;i<que;i++)
{
scanf("%d%d",&Q[i].x,&Q[i].y);
Q[i].kk=i;
}
qsort(Q,que,sizeof(Q[0]),cmpy);
int j=0;
for(i=0;i<que;i++)
{
while(j<n-1&&e[j].w<=Q[i].y)
{
if(deep[e[j].u]<deep[e[j].v])
swap(e[j].u,e[j].v);
updata(p[e[j].u],e[j].w,1);
j++;
}
cnt[Q[i].kk]=findmax(1,Q[i].x);
if(cnt[Q[i].kk]<=-inf)
cnt[Q[i].kk]=-1;
}
for(i=0;i<que;i++)
printf("%d\n",cnt[i]);
}
return 0;
}