zoukankan      html  css  js  c++  java
  • SPOJ 375. Query on a tree (动态树)

    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 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 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013-9-3 21:06:05
      4 File Name     :F:2013ACM练习专题学习动态树-LCTSPOJQTREE.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 #include <time.h>
     19 using namespace std;
     20 
     21 //对一颗树,进行两个操作:
     22 //1.修改边权
     23 //2.查询u->v路径上边权的最大值
     24 const int MAXN = 10010;
     25 int ch[MAXN][2],pre[MAXN];
     26 int Max[MAXN],key[MAXN];
     27 bool rt[MAXN];
     28 void push_down(int r)
     29 {
     30     
     31 }
     32 void push_up(int r)
     33 {
     34     Max[r] = max(max(Max[ch[r][0]],Max[ch[r][1]]),key[r]);
     35 }
     36 void Rotate(int x)
     37 {
     38     int y = pre[x], kind = ch[y][1]==x;
     39     ch[y][kind] = ch[x][!kind];
     40     pre[ch[y][kind]] = y;
     41     pre[x] = pre[y];
     42     pre[y] = x;
     43     ch[x][!kind] = y;
     44     if(rt[y])
     45         rt[y] = false, rt[x] = true;
     46     else 
     47         ch[pre[x]][ch[pre[x]][1]==y] = x;
     48     push_up(y);
     49 }
     50 void P(int r)
     51 {
     52     if(!rt[r])P(pre[r]);
     53     push_down(r);
     54 }
     55 void Splay(int r)
     56 {
     57     //P(r);
     58     while( !rt[r] )
     59     {
     60         int f = pre[r], ff = pre[f];
     61         if(rt[f])
     62             Rotate(r);
     63         else if( (ch[ff][1]==f)==(ch[f][1]==r) )
     64             Rotate(f), Rotate(r);
     65         else
     66             Rotate(r), Rotate(r);
     67     }
     68     push_up(r);
     69 }
     70 int Access(int x)
     71 {
     72     int y = 0;
     73     do
     74     {
     75         Splay(x);
     76         rt[ch[x][1]] = true, rt[ch[x][1]=y] = false;
     77         push_up(x);
     78         x = pre[y=x];
     79     }
     80     while(x);
     81     return y;
     82 }
     83 //调用后u是原来u和v的lca,v和ch[u][1]分别存着lca的2个儿子
     84 //(原来u和v所在的2颗子树)
     85 void lca(int &u,int &v)
     86 {
     87     Access(v), v = 0;
     88     while(u)
     89     {
     90         Splay(u);
     91         if(!pre[u])return;
     92         rt[ch[u][1]] = true;
     93         rt[ch[u][1]=v] = false;
     94         push_up(u);
     95         u = pre[v = u];
     96     }
     97 }
     98 
     99 void change(int u,int k)
    100 {
    101     Access(u);
    102     key[u] = k;
    103     push_up(u);
    104 }
    105 void query(int u,int v)
    106 {
    107     lca(u,v);
    108     printf("%d
    ",max(Max[v],Max[ch[u][1]]));
    109 }
    110 
    111 struct Edge
    112 {
    113     int to,next;
    114     int val;
    115     int index;
    116 }edge[MAXN*2];
    117 int head[MAXN],tot;
    118 int id[MAXN];
    119 
    120 void addedge(int u,int v,int val,int index)
    121 {
    122     edge[tot].to = v;
    123     edge[tot].next = head[u];
    124     edge[tot].val = val;
    125     edge[tot].index = index;
    126     head[u] = tot++;
    127 }
    128 void dfs(int u)
    129 {
    130     for(int i = head[u];i != -1;i = edge[i].next)
    131     {
    132         int v = edge[i].to;
    133         if(pre[v] != 0)continue;
    134         pre[v] = u;
    135         id[edge[i].index] = v;
    136         key[v] = edge[i].val;
    137         dfs(v);
    138     }
    139 }
    140 void init()
    141 {
    142     tot = 0;
    143     memset(head,-1,sizeof(head));
    144 }
    145 int main()
    146 {
    147     //freopen("in.txt","r",stdin);
    148     //freopen("out.txt","w",stdout);
    149     int T;
    150     int n;
    151     int u,v,w;
    152     char op[20];
    153     scanf("%d",&T);
    154     while(T--)
    155     {
    156         init();
    157         scanf("%d",&n);
    158         for(int i = 0;i <= n;i++)
    159         {
    160             pre[i] = 0;
    161             ch[i][0] = ch[i][1] = 0;
    162             rt[i] = true;
    163         }
    164         Max[0] = -2000000000;
    165         for(int i = 1;i < n;i++)
    166         {
    167             scanf("%d%d%d",&u,&v,&w);
    168             addedge(u,v,w,i);
    169             addedge(v,u,w,i);
    170         }
    171         pre[1] = -1;
    172         dfs(1);
    173         pre[1] = 0;
    174         while(scanf("%s",&op) == 1)
    175         {
    176             if(op[0] == 'D')break;
    177             scanf("%d%d",&u,&v);
    178             if(op[0] == 'C')
    179                 change(id[u],v);
    180             else query(u,v);
    181         }
    182     }
    183     return 0;
    184 }
  • 相关阅读:
    海康视频 rtnp转 flv
    生成随机不重复数列表(C#)
    保证应用程序只运行一个实例[c#]
    [C++] C++指针的那些事 常量,变量,指针及指针相关的三个数值
    C#压缩与解压缩流类 GZipStream 的使用
    [C# WinFrom 使用 Google Map] 在地图上画轨迹线
    一个泛型应用示例
    没五笔,不写了
    利用Socket HTTP协议获得HTML代码方法
    Remoting实例(客户端发送信息)
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3300217.html
Copyright © 2011-2022 走看看