Query on a tree
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1248 Accepted Submission(s): 305
Problem Description
There are some queries on a tree which has n nodes. Every query is described as two integers (X, Y).For each query, you should find the maximum weight of the edges in set E, which satisfies the following two conditions.
1) The edge must on the path from node X to node 1.
2) The edge’s weight should be lower or equal to Y.
Now give you the tree and queries. Can you find out the answer for each query?
1) The edge must on the path from node X to node 1.
2) The edge’s weight should be lower or equal to Y.
Now give you the tree and queries. Can you find out the answer for each query?
Input
The first line of the input is an integer T, indicating the number of test cases. For each case, the first line contains an integer n indicates the number of nodes in the tree. Then n-1 lines follows, each line contains three integers X, Y, W indicate an edge between node X and node Y whose value is W. Then one line has one integer Q indicates the number of queries. In the next Q lines, each line contains two integers X and Y as said above.
Output
For each test case, you should output Q lines. If no edge satisfy the conditions described above,just output “-1” for this query. Otherwise output the answer for this query.
Sample Input
1 3 1 2 7 2 3 5 4 3 10 3 7 3 6 3 4
Sample Output
7 7 5 -1Hint2<=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.
Author
Edward_mj
Source
给定一棵树,每条边有边权,询问每个点到1号节点路径上的所有边权中不超过y的最大值。
利用线段树,所有边权先设为负。
把边和询问按权值排序,保证每次查询之前所有比限制的最大边权大的边都没有在线段树中更新,这样就可以直接在线段树当中查询最大值。
代码长得可怕,3540B。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=100001,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int size[maxn],son[maxn],fa[maxn],top[maxn],dep[maxn],dfn[maxn];
int ans[maxn];
bool visit[maxn];
int num;
vector<int> v[maxn];
struct Mayer{
int x,y,d;
};
Mayer a[maxn];
bool cmp(Mayer a,Mayer b) {
return a.d<b.d;
}
struct query {
int x,y,id;
};
query q[maxn];
bool cmp2(query a,query b) {
return a.y<b.y;
}
void addedge(int from,int to) {
v[from].push_back(to);
v[to].push_back(from);
}
int dfs(int now,int step) {
visit[now]=1;son[now]=-1;dep[now]=step;size[now]=1;
for (int i=0;i<v[now].size();i++) {
int to=v[now][i];
if (!visit[to]) {
fa[to]=now;
size[now]+=dfs(to,step+1);
if (son[now]==-1||size[to]>size[son[now]]) son[now]=to;
}
}
return size[now];
}
void dfs2(int now,int t) {
visit[now]=1;top[now]=t;dfn[now]=++num;
if (son[now]!=-1) dfs2(son[now],t);
for (int i=0;i<v[now].size();i++) {
int to=v[now][i];
if (!visit[to])
dfs2(to,to);
}
}
struct Tree {
int l,r,lc,rc,max;
};
Tree tree[4*maxn];
void build(int now,int l,int r) {
tree[now].l=l;tree[now].r=r;
if (l==r) {
tree[now].max=-1;
} else {
num++;
tree[now].lc=num;
build(num,l,(l+r)/2);
num++;
tree[now].rc=num;
build(num,(l+r)/2+1,r);
tree[now].max=max(tree[tree[now].lc].max,tree[tree[now].rc].max);
}
}
void update(int now,int pos,int val) {
// cout << tree[now].l << ' ' << tree[now].r << ' ' << tree[now].max << endl;
if (tree[now].l==tree[now].r&&tree[now].l==pos) {
tree[now].max=val;
} else {
if (pos<=(tree[now].l+tree[now].r)/2)
update(tree[now].lc,pos,val);
if (pos>(tree[now].l+tree[now].r)/2)
update(tree[now].rc,pos,val);
tree[now].max=max(tree[tree[now].lc].max,tree[tree[now].rc].max);
}
// cout << tree[now].l << ' ' << tree[now].r << ' ' << tree[now].max << endl;
}
int findmax(int now,int l,int r) {
if (tree[now].l>=l&&tree[now].r<=r) {
return tree[now].max;
} else {
int ans=-inf;
if (l<=(tree[now].l+tree[now].r)/2)
ans=max(ans,findmax(tree[now].lc,l,r));
if (r>(tree[now].l+tree[now].r)/2)
ans=max(ans,findmax(tree[now].rc,l,r));
return ans;
}
}
int findval(int u) {
int x=top[u],ans=-1;
while (x!=1) {
ans=max(ans,findmax(1,dfn[x]-1,dfn[u]-1));
u=fa[x];x=top[u];
}
ans=max(ans,findmax(1,dfn[son[x]]-1,dfn[u]-1));
return ans;
}
int main() {
int cas;
scanf("%d",&cas);
while (cas--) {
int n,i,j,m;
scanf("%d",&n);
for (i=1;i<n;i++) {
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].d);
addedge(a[i].x,a[i].y);
}
mem0(visit);
dfs(1,0);
mem0(visit);
num=0;
dfs2(1,1);
sort(a+1,a+n,cmp);
scanf("%d",&m);
build(1,1,n-1);
for (i=1;i<=m;i++) {
scanf("%d%d",&q[i].x,&q[i].y);
q[i].id=i;
}
sort(q+1,q+m+1,cmp2);
j=1;
for (i=1;i<=m;i++) {
while (a[j].d<=q[i].y&&j<n) {
update(1,max(dfn[a[j].x],dfn[a[j].y])-1,a[j].d);
j++;
}
ans[q[i].id]=findval(q[i].x);
}
for (i=1;i<=m;i++) printf("%d\n",ans[i]);
for (i=1;i<=n;i++) v[i].clear();
}
return 0;
}