spoj375 Query on a tree(树链剖分)
2016-05-22 15:51
447 查看
思路:树链剖分的模板
Description
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
CHANGE i ti : change the cost of the i-th edge to ti
or
QUERY a b : ask for the maximum edge cost on the path from node a to node b
For each test case:
In the first line there is an integer N (N <= 10000),
In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c<= 1000000),
The next lines contain instructions "CHANGE i ti" or "QUERY a b",
The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Hint
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define Del(a,b) memset(a,b,sizeof(a)) const int N = 10005; int dep ,siz ,fa ,id ,son ,val ,top ; //top 最近的重链父节点 int num; vector<int> v ; struct tree { int x,y,val; void read(){ scanf("%d%d%d",&x,&y,&val); } }; tree e ; void dfs1(int u, int f, int d) { dep[u] = d; siz[u] = 1; son[u] = 0; fa[u] = f; for (int i = 0; i < v[u].size(); i++) { int ff = v[u][i]; if (ff == f) continue; dfs1(ff, u, d + 1); siz[u] += siz[ff]; if (siz[son[u]] < siz[ff]) son[u] = ff; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++num; if (son[u]) dfs2(son[u], tp); for (int i = 0; i < v[u].size(); i++) { int ff = v[u][i]; if (ff == fa[u] || ff == son[u]) continue; dfs2(ff, ff); } } #define lson(x) ((x<<1)) #define rson(x) ((x<<1)+1) struct Tree { int l,r,val; }; Tree tree[4*N]; void pushup(int x) { tree[x].val = max(tree[lson(x)].val, tree[rson(x)].val); } void build(int l,int r,int v) { tree[v].l=l; tree[v].r=r; if(l==r) { tree[v].val = val[l]; return ; } int mid=(l+r)>>1; build(l,mid,v*2); build(mid+1,r,v*2+1); pushup(v); } void update(int o,int v,int val) //log(n) { if(tree[o].l==tree[o].r) { tree[o].val = val; return ; } int mid = (tree[o].l+tree[o].r)/2; if(v<=mid) update(o*2,v,val); else update(o*2+1,v,val); pushup(o); } int query(int x,int l, int r) { if (tree[x].l >= l && tree[x].r <= r) { return tree[x].val; } int mid = (tree[x].l + tree[x].r) / 2; int ans = 0; if (l <= mid) ans = max(ans, query(lson(x),l,r)); if (r > mid) ans = max(ans, query(rson(x),l,r)); return ans; } int Yougth(int u, int v) { int tp1 = top[u], tp2 = top[v]; int ans = 0; while (tp1 != tp2) { //printf("YES\n"); if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } ans = max(query(1,id[tp1], id[u]), ans); u = fa[tp1]; tp1 = top[u]; } if (u == v) return ans; if (dep[u] > dep[v]) swap(u, v); ans = max(query(1,id[son[u]], id[v]), ans); return ans; } void Clear(int n) { for(int i=1;i<=n;i++) v[i].clear(); } int main() { //freopen("Input.txt","r",stdin); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<n;i++) { e[i].read(); v[e[i].x].push_back(e[i].y); v[e[i].y].push_back(e[i].x); } num = 0; dfs1(1,0,1); dfs2(1,1); for (int i = 1; i < n; i++) { if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y); val[id[e[i].x]] = e[i].val; } build(1,num,1); char s[200]; while(~scanf("%s",&s) && s[0]!='D') { int x,y; scanf("%d%d",&x,&y); if(s[0]=='Q') printf("%d\n",Yougth(x,y)); if (s[0] == 'C') update(1,id[e[x].x],y); } Clear(n); } return 0; }
Description
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
CHANGE i ti : change the cost of the i-th edge to ti
or
QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.For each test case:
In the first line there is an integer N (N <= 10000),
In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c<= 1000000),
The next lines contain instructions "CHANGE i ti" or "QUERY a b",
The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "QUERY" operation, write one integer representing its result.Example
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
Hint
Added by: | Thanh-Vy Hua |
Date: | 2005-06-08 |
Time limit: | 0.851s |
Source limit: | 15000B |
Memory limit: | 1536MB |
Cluster: | Cube (Intel G860) |
Languages: | ADA ASM BASH BF C C# C++ 5 CLPS LISP sbcl LISP clisp D FORT HASK ICON ICK JAVA LUA NEM NICE CAML PAS gpc PAS fpc PERL PHP PIKE PRLG PYTH 2.7 RUBY SCM qobi SCM guile ST TEXT WSPC |
相关文章推荐
- iOS开发UI篇—UIWindow简单介绍
- leetcode 096 Unique Binary Search Trees
- Uva1152——4 Values whose Sum is 0
- arduino 和 雨滴传感器 滴水实验
- Duilib教程-HelloDuilib及DuiDesigner的简单使用
- UIToolBar使用示例
- iOS开发 - 第02篇 - UI进阶 - 05 - QQ好友列表
- UITableView 头部图片 图片拉伸
- JAVA/GUI程序之记事本
- JAVA/GUI程序之记事本
- 第一次写Hbuilder的三方插件
- PKU 3368 Frequent values 线段树
- poj 3368 Frequent values 线段树
- 学员信息录入(StuInfoManager) 用分层实现(既MySchool后的一个案例)
- APUE------进程间通信
- Randomized quicksort
- bzoj 1005: [HNOI2008]明明的烦恼(组合数学 purfer sequence)
- Frequent Pattern 挖掘之二(FP Growth算法)(转)
- LeetCode:Implement Queue using Stacks
- LeetCode:Implement Stack using Queues