• spoj 375 Query on a tree (树链剖分)


    题目链接: http://www.spoj.com/problems/QTREE/

    题意:

    给一颗树,每条边有一个权值。有两种操作:

    1、修改某条边的值;

    2、询问a、b两点路径上边权的最大值。

    分析:树链剖分模板题

    代码如下:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 
      6 using namespace std;
      7 const int maxn=10010;
      8 
      9 struct Edge
     10 {
     11     int to,next;
     12 }edge[maxn*2];
     13 int head[maxn];
     14 int cnt,tmp,n;
     15 int dep[maxn],fa[maxn],size[maxn],son[maxn],top[maxn],id[maxn],rank[maxn];
     16 struct Node
     17 {
     18     int u,v,c;
     19 }node[maxn];
     20 
     21 void init()
     22 {
     23     memset(head,-1,sizeof(head));
     24     memset(son,-1,sizeof(son));
     25     tmp=0;
     26     cnt=0;
     27 }
     28 
     29 void addedge(int u,int v)
     30 {
     31     edge[cnt].to=v;
     32     edge[cnt].next=head[u];
     33     head[u]=cnt++;
     34 }
     35 
     36 void dfs_1(int u,int f,int d)
     37 {
     38     dep[u]=d;
     39     size[u]=1;
     40     fa[u]=f;
     41     for(int i=head[u];i!=-1;i=edge[i].next)
     42     {
     43         int v=edge[i].to;
     44         if(v==f)
     45             continue;
     46         dfs_1(v,u,d+1);
     47         size[u]+=size[v];
     48         if(son[u]==-1||size[son[u]]<size[v])
     49             son[u]=v;
     50     }
     51 }
     52 
     53 void dfs_2(int u,int tp)
     54 {
     55     top[u]=tp;
     56     id[u]=++tmp;
     57     rank[id[u]]=u;
     58     if(son[u]!=-1)
     59         dfs_2(son[u],tp);
     60     for(int i=head[u];i!=-1;i=edge[i].next)
     61     {
     62         int v=edge[i].to;
     63         if(v!=fa[u]&&v!=son[u])
     64             dfs_2(v,v);
     65     }
     66 }
     67 struct Tree
     68 {
     69     int left,right;
     70     int m;
     71 }tree[maxn*4];
     72 
     73 void pushup(int i)
     74 {
     75     tree[i].m=max(tree[i*2].m,tree[i*2+1].m);
     76 }
     77 
     78 void build(int i,int begin,int end)
     79 {
     80     tree[i].left=begin;
     81     tree[i].right=end;
     82     tree[i].m=0;
     83     if(begin==end)
     84         return;
     85     int mid=(begin+end)/2;
     86     build(i*2,begin,mid);
     87     build(i*2+1,mid+1,end);
     88 }
     89 
     90 void update(int i,int k,int val)
     91 {
     92     if(tree[i].left==k&&tree[i].right==k)
     93     {
     94         tree[i].m=val;
     95         return;
     96     }
     97     int mid=(tree[i].left+tree[i].right)/2;
     98     if(k<=mid)
     99         update(i*2,k,val);
    100     else
    101         update(i*2+1,k,val);
    102     pushup(i);
    103 }
    104 
    105 int query(int i,int begin,int end)
    106 {
    107     if(tree[i].left>=begin&&tree[i].right<=end)
    108         return tree[i].m;
    109     int mid=(tree[i].left+tree[i].right)/2;
    110     int res=0;
    111     if(mid>=begin)
    112         res=max(res,query(i*2,begin,end));
    113     if(mid<end)
    114         res=max(res,query(i*2+1,begin,end));
    115     return res;
    116 }
    117 
    118 int find(int u,int v)
    119 {
    120     int tp1=top[u],tp2=top[v];
    121     int res=0;
    122     while(tp1!=tp2)
    123     {
    124         if(dep[tp1]<dep[tp2])
    125         {
    126             swap(tp1,tp2);
    127             swap(u,v);
    128         }
    129         res=max(res,query(1,id[tp1],id[u]));
    130         u=fa[tp1];
    131         tp1=top[u];
    132     }
    133     if(u==v)
    134         return res;
    135     if(dep[u]>dep[v])
    136         swap(u,v);
    137     res=max(res,query(1,id[son[u]],id[v]));
    138     return res;
    139 }
    140 
    141 int main()
    142 {
    143     int t;
    144     scanf("%d",&t);
    145     while(t--)
    146     {
    147         init();
    148         scanf("%d",&n);
    149         for(int i=1;i<n;i++)
    150         {
    151             scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].c);
    152             addedge(node[i].u,node[i].v);
    153             addedge(node[i].v,node[i].u);
    154         }
    155         dfs_1(1,0,1);
    156         dfs_2(1,1);
    157         build(1,1,tmp);
    158         for(int i=1;i<n;i++)
    159         {
    160             if(dep[node[i].u]>dep[node[i].v])
    161                 swap(node[i].u,node[i].v);
    162             update(1,id[node[i].v],node[i].c);
    163         }
    164         char s[20];
    165         int num,cost;
    166         while(1)
    167         {
    168             scanf("%s",s);
    169             if(s[0]=='D')
    170                 break;
    171             else if(s[0]=='C')
    172             {
    173                 scanf("%d%d",&num,&cost);
    174                 update(1,id[node[num].v],cost);
    175             }
    176             else
    177             {
    178                 int a,b;
    179                 scanf("%d%d",&a,&b);
    180                 printf("%d
    ",find(a,b));
    181             }
    182         }
    183     }
    184     return 0;
    185 }
  • 相关阅读:
    Java基础——消息队列
    Java基础——缓存
    Java基础——动态代理
    Java基础——克隆
    Java基础——锁
    Java基础——线程池
    Java基础——线程
    Java基础——HashMap
    Java基础——String
    SpringMVC的学习____5.乱码问题的解决_两种方法(两个类)
  • 原文地址:https://www.cnblogs.com/yaoyueduzhen/p/5311184.html
Copyright © 2020-2023  润新知