码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ QTREE Query on a tree

时间:2015-09-19 21:08:43      阅读:360      评论:0      收藏:0      [点我收藏+]

标签:

Query on a tree

Time Limit: 5000ms
Memory Limit: 262144KB
This problem will be judged on SPOJ. Original ID: QTREE
64-bit integer IO format: %lld      Java class name: Main
 

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 ab 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

解题:树链剖分

技术分享
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 10100;
  4 struct arc{
  5     int to,next;
  6     arc(int x = 0,int y = -1){
  7         to = x;
  8         next = y;
  9     }
 10 }e[30000];
 11 struct node{
 12     int lt,rt,val;
 13 }tree[maxn<<2];
 14 int head[maxn],fa[maxn],dep[maxn],son[maxn],tot;
 15 int siz[maxn],top[maxn],tid[maxn],label;
 16 void add(int u,int v){
 17     e[tot] = arc(v,head[u]);
 18     head[u] = tot++;
 19 }
 20 void Find_heavy_edge(int u,int father,int depth){
 21     siz[u] = 1;
 22     dep[u] = depth;
 23     fa[u] = father;
 24     son[u] = -1;
 25     for(int i = head[u]; ~i; i = e[i].next){
 26         if(e[i].to == father) continue;
 27         Find_heavy_edge(e[i].to,u,depth + 1);
 28         siz[u] += siz[e[i].to];
 29         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
 30             son[u] = e[i].to;
 31     }
 32 }
 33 void connect_heavy_edge(int u,int ancestor){
 34     tid[u] = label++;
 35     top[u] = ancestor;
 36     for(int i = head[u]; ~i; i = e[i].next){
 37         if(e[i].to == fa[u]) continue;
 38         if(e[i].to == son[u]) connect_heavy_edge(e[i].to,ancestor);
 39         else connect_heavy_edge(e[i].to,e[i].to);
 40     }
 41 }
 42 inline void pushup(int v){
 43     tree[v].val = max(tree[v<<1].val,tree[v<<1|1].val);
 44 }
 45 void build(int lt,int rt,int v){
 46     tree[v].lt = lt;
 47     tree[v].rt = rt;
 48     tree[v].val = 0;
 49     if(lt == rt) return;
 50     int mid = (lt + rt)>>1;
 51     build(lt,mid,v<<1);
 52     build(mid+1,rt,v<<1|1);
 53 }
 54 void update(int pos,int val,int v){
 55     if(tree[v].lt == tree[v].rt){
 56         tree[v].val = val;
 57         return;
 58     }
 59     if(pos <= tree[v<<1].rt) update(pos,val,v<<1);
 60     if(pos >= tree[v<<1|1].lt) update(pos,val,v<<1|1);
 61     pushup(v);
 62 }
 63 int query(int lt,int rt,int v){
 64     int ret = 0;
 65     if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].val;
 66     if(lt <= tree[v<<1].rt) ret = query(lt,rt,v<<1);
 67     if(rt >= tree[v<<1|1].lt) ret = max(ret,query(lt,rt,v<<1|1));
 68     return ret;
 69 }
 70 int Find(int u,int v){
 71     int f1 = top[u],f2 = top[v],tmp = 0;
 72     while(f1 != f2){
 73         if(dep[f1] < dep[f2]){
 74             swap(f1,f2);
 75             swap(u,v);
 76         }
 77         tmp = max(tmp,query(tid[f1],tid[u],1));
 78         u = fa[f1];
 79         f1 = top[u];
 80     }
 81     if(u == v) return tmp;
 82     if(dep[u] > dep[v]) swap(u,v);
 83     return max(tmp,query(tid[son[u]],tid[v],1));
 84 }
 85 int ac[maxn][3];
 86 int main(){
 87     int kase,n,u,v;
 88     char op[10];
 89     scanf("%d",&kase);
 90     while(kase--){
 91         memset(head,-1,sizeof head);
 92         scanf("%d",&n);
 93         for(int i = tot = 0; i < n-1; ++i){
 94             scanf("%d%d%d",&ac[i][0],&ac[i][1],&ac[i][2]);
 95             add(ac[i][0],ac[i][1]);
 96             add(ac[i][1],ac[i][0]);
 97         }
 98         label = 0;
 99         Find_heavy_edge(1,0,0);
100         connect_heavy_edge(1,1);
101         build(0,label-1,1);
102         for(int i = 0; i < n-1; ++i){
103             if(dep[ac[i][0]] > dep[ac[i][1]])
104                 swap(ac[i][0],ac[i][1]);
105             update(tid[ac[i][1]],ac[i][2],1);
106         }
107         while(~scanf("%s",op)){
108             if(op[0] == D) break;
109             scanf("%d%d",&u,&v);
110             if(op[0] == Q) printf("%d\n",Find(u,v));
111             else update(tid[ac[u-1][1]],v,1);
112         }
113     }
114     return 0;
115 }
View Code

 

SPOJ QTREE Query on a tree

标签:

原文地址:http://www.cnblogs.com/crackpotisback/p/4822059.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!