SPOJ 375. 나무 에 쿼 리 (나무 사슬 분할)

28612 단어 query
제목 링크:
http://www.spoj.com/problems/QTREE/
 
375. Query on a tree Problem code: QTREE
 
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 tior
  • 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
    

     
    나무 사슬 분할 입문 문제:
     
     
      1 /* **********************************************
      2 Author      : kuangbin
      3 Created Time: 2013/8/11 22:00:02
      4 File Name   : F:\2013ACM  \    \    \SPOJ_QTREE.cpp
      5 *********************************************** */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 using namespace std;
     19 
     20 const int MAXN = 10010;
     21 struct Edge
     22 {
     23     int to,next;
     24 }edge[MAXN*2];
     25 int head[MAXN],tot;
     26 int top[MAXN];//top[v]  v          
     27 int fa[MAXN]; //    
     28 int deep[MAXN];//  
     29 int num[MAXN];//num[v]   v         
     30 int p[MAXN];//p[v]  v                 
     31 int fp[MAXN];// p    
     32 int son[MAXN];//   
     33 int pos;
     34 void init()
     35 {
     36     tot = 0;
     37     memset(head,-1,sizeof(head));
     38     pos = 0;
     39     memset(son,-1,sizeof(son));
     40 }
     41 void addedge(int u,int v)
     42 {
     43     edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
     44 }
     45 void dfs1(int u,int pre,int d) //   dfs  fa,deep,num,son
     46 {
     47     deep[u] = d;
     48     fa[u] = pre;
     49     num[u] = 1;
     50     for(int i = head[u];i != -1; i = edge[i].next)
     51     {
     52         int v = edge[i].to;
     53         if(v != pre)
     54         {
     55             dfs1(v,u,d+1);
     56             num[u] += num[v];
     57             if(son[u] == -1 || num[v] > num[son[u]])
     58                 son[u] = v;
     59         }
     60     }
     61 }
     62 void getpos(int u,int sp) //   dfs  top p
     63 {
     64     top[u] = sp;
     65     if(son[u] != -1)
     66     {
     67         p[u] = pos++;
     68         fp[p[u]] = u;
     69         getpos(son[u],sp);
     70     }
     71     else
     72     {
     73         p[u] = pos++;
     74         fp[p[u]] = u;
     75         return;
     76     }
     77     for(int i = head[u] ; i != -1; i = edge[i].next)
     78     {
     79         int v = edge[i].to;
     80         if(v != son[u] && v != fa[u])
     81             getpos(v,v);
     82     }
     83 }
     84 
     85 //   
     86 struct Node
     87 {
     88     int l,r;
     89     int Max;
     90 }segTree[MAXN*3];
     91 void build(int i,int l,int r)
     92 {
     93     segTree[i].l = l;
     94     segTree[i].r = r;
     95     segTree[i].Max = 0;
     96     if(l == r)return;
     97     int mid = (l+r)/2;
     98     build(i<<1,l,mid);
     99     build((i<<1)|1,mid+1,r);
    100 }
    101 void push_up(int i)
    102 {
    103     segTree[i].Max = max(segTree[i<<1].Max,segTree[(i<<1)|1].Max);
    104 }
    105 void update(int i,int k,int val) //        k   val
    106 {
    107     if(segTree[i].l == k && segTree[i].r == k)
    108     {
    109         segTree[i].Max = val;
    110         return;
    111     }
    112     int mid = (segTree[i].l + segTree[i].r)/2;
    113     if(k <= mid)update(i<<1,k,val);
    114     else update((i<<1)|1,k,val);
    115     push_up(i);
    116 }
    117 int query(int i,int l,int r)  //      [l,r]     
    118 {
    119     if(segTree[i].l == l && segTree[i].r == r)
    120         return segTree[i].Max;
    121     int mid = (segTree[i].l + segTree[i].r)/2;
    122     if(r <= mid)return query(i<<1,l,r);
    123     else if(l > mid)return query((i<<1)|1,l,r);
    124     else return max(query(i<<1,l,mid),query((i<<1)|1,mid+1,r));
    125 }
    126 int find(int u,int v)//  u->v     
    127 {
    128     int f1 = top[u], f2 = top[v];
    129     int tmp = 0;
    130     while(f1 != f2)
    131     {
    132         if(deep[f1] < deep[f2])
    133         {
    134             swap(f1,f2);
    135             swap(u,v);
    136         }
    137         tmp = max(tmp,query(1,p[f1],p[u]));
    138         u = fa[f1]; f1 = top[u];
    139     }
    140     if(u == v)return tmp;
    141     if(deep[u] > deep[v]) swap(u,v);
    142     return max(tmp,query(1,p[son[u]],p[v]));
    143 }
    144 int e[MAXN][3];
    145 int main()
    146 {
    147     //freopen("in.txt","r",stdin);
    148     //freopen("out.txt","w",stdout);
    149     int T;
    150     int n;
    151     scanf("%d",&T);
    152     while(T--)
    153     {
    154         init();
    155         scanf("%d",&n);
    156         for(int i = 0;i < n-1;i++)
    157         {
    158             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
    159             addedge(e[i][0],e[i][1]);
    160             addedge(e[i][1],e[i][0]);
    161         }
    162         dfs1(1,0,0);
    163         getpos(1,1);
    164         build(1,0,pos-1);
    165         for(int i = 0;i < n-1; i++)
    166         {
    167             if(deep[e[i][0]] > deep[e[i][1]])
    168                 swap(e[i][0],e[i][1]);
    169             update(1,p[e[i][1]],e[i][2]);
    170         }
    171         char op[10];
    172         int u,v;
    173         while(scanf("%s",op) == 1)
    174         {
    175             if(op[0] == 'D')break;
    176             scanf("%d%d",&u,&v);
    177             if(op[0] == 'Q')
    178                 printf("%d
    ",find(u,v)); 179 else update(1,p[e[u-1][1]],v); 180 } 181 } 182 return 0; 183 }

     

    좋은 웹페이지 즐겨찾기