题目链接: 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 }

转载于:https://www.cnblogs.com/yaoyueduzhen/p/5311184.html

spoj 375 Query on a tree (树链剖分)相关推荐

  1. SPOJ 375 query on a tree 树链剖分

    题意: 给一棵树型数据结构 ①支持修改边的权值      ②支持成段边权最值查询 树链剖分入门题. 树链剖分+线段树 用的notonlysuccess的线段树--不开结构体事先预处理的那种 我以前写的 ...

  2. SPOJ - QTREE Query on a tree(树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型: QUERY x y:询问点x-点y这条路径上的所有边权的最大值 CHANGE x y:将第x条边的权 ...

  3. HDU - 3804 Query on a tree(树链剖分+线段树+离线处理)

    题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...

  4. SPOJ Query on a tree 树链剖分 边修改

    链接 提交链接 题解 对边的修改算到点上 只需要修改下面的地方 代码 #include<bits/stdc++.h> #define N 10010 #define INF 0x3f3f3 ...

  5. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  6. spoj 375 Query on a tree

    题意:给一棵树,节点数不超过10000,有两个操作:1.询问a,b路径上最长的边长.2.把第a条边长度改为b. p.s.人生中第一个树链剖分,尼玛debug了好久好久我擦... 分析:轻重边路径剖分, ...

  7. POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘...

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12247   Accepted: 3151 Descriptio ...

  8. CodeForces - 343D Water Tree(树链剖分+线段树)

    题目链接: 题目大意:给出一棵由n个点组成的树,初始时每个点的权值为0,接下来有m个操作,每个操作分为以下三种: 1 x:将包括节点x在内的所有子孙节点的权值都改为1 2 x:将包括节点x在内的所有父 ...

  9. 计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)

    题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:因为一开始不会主席 ...

最新文章

  1. Selenium自动化-清空输入框、输入内容、点击按钮
  2. 【面向对象设计模式】 适配器模式 (二)
  3. win7台式电脑怎么连wifi_修改WiFi密码后电脑连不上网如何解决 修改WiFi密码后电脑连不上网解决方法【详解】...
  4. [Qt教程] 第27篇 XML(一)使用DOM读取XML文档
  5. 【jq插件】Grade-打分效果
  6. 关于左移右移的操作 学习
  7. mysql mssql 性能对比_详解mysql分区实验测试--非分区表与分区表的性能对比
  8. 51单片机4位抢答器_倒计时可调仿真设计
  9. C语言冒泡排序(函数版)
  10. 沙箱 sandbox
  11. 双网卡(内外网)配置,路由+DNS
  12. 软件工程——团队作业2
  13. ios如何解除dns被劫持_iPhone被DNS劫持,老跳广告咋办?
  14. 【阿里云总监课】存储系统设计——NVMe SSD性能影响因素一探究竟
  15. 推荐几个程序员Mac m1max芯片笔记本软件
  16. 洗扑克牌 (乱数排序)
  17. 剑指offer-丑数(Java)
  18. 令人愉悦的性能统计分析工具-hiper 【发个copy】
  19. 拉普拉斯变形的原理解析和python代码
  20. java sl4j 日志_为Java项目添加slf4j的log日志-阿里云开发者社区

热门文章

  1. 【机器视觉】 ifelse算子(已废弃)
  2. S如何边缘控制_如何用尼康佳能索尼人像标头50mm/1.8拍出大片的效果?
  3. 广东省计算机大赛设计什么时候,2017年广东省大学生计算机设计大赛
  4. php 中session与cookies的区别,php中session和cookie的区别
  5. mysql隔离级别 举例_mysql的事务隔离级别举例
  6. zookeeper快速入门,配置虚拟机ip、mac、虚拟机免密,jdk的安装与卸载
  7. 合并两个有序数组—leetcode88
  8. java hashmap 输出_JAVA如何把HashMap内容输出到文本文件
  9. matlab偶极矩电场强度分布图_物理-电磁学|第三讲|静电场中的电介质
  10. Delphi程序自删除