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\n",find(a,b));
181             }
182         }
183     }
184     return 0;
185 }

 

posted @ 2016-03-23 15:03  邀月独斟  阅读(177)  评论(0编辑  收藏  举报