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 }
转载于:https://www.cnblogs.com/yaoyueduzhen/p/5311184.html
spoj 375 Query on a tree (树链剖分)相关推荐
- SPOJ 375 query on a tree 树链剖分
题意: 给一棵树型数据结构 ①支持修改边的权值 ②支持成段边权最值查询 树链剖分入门题. 树链剖分+线段树 用的notonlysuccess的线段树--不开结构体事先预处理的那种 我以前写的 ...
- SPOJ - QTREE Query on a tree(树链剖分+线段树)
题目链接:点击查看 题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型: QUERY x y:询问点x-点y这条路径上的所有边权的最大值 CHANGE x y:将第x条边的权 ...
- HDU - 3804 Query on a tree(树链剖分+线段树+离线处理)
题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...
- SPOJ Query on a tree 树链剖分 边修改
链接 提交链接 题解 对边的修改算到点上 只需要修改下面的地方 代码 #include<bits/stdc++.h> #define N 10010 #define INF 0x3f3f3 ...
- 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 ...
- spoj 375 Query on a tree
题意:给一棵树,节点数不超过10000,有两个操作:1.询问a,b路径上最长的边长.2.把第a条边长度改为b. p.s.人生中第一个树链剖分,尼玛debug了好久好久我擦... 分析:轻重边路径剖分, ...
- POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘...
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12247 Accepted: 3151 Descriptio ...
- CodeForces - 343D Water Tree(树链剖分+线段树)
题目链接: 题目大意:给出一棵由n个点组成的树,初始时每个点的权值为0,接下来有m个操作,每个操作分为以下三种: 1 x:将包括节点x在内的所有子孙节点的权值都改为1 2 x:将包括节点x在内的所有父 ...
- 计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)
题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:因为一开始不会主席 ...
最新文章
- Selenium自动化-清空输入框、输入内容、点击按钮
- 【面向对象设计模式】 适配器模式 (二)
- win7台式电脑怎么连wifi_修改WiFi密码后电脑连不上网如何解决 修改WiFi密码后电脑连不上网解决方法【详解】...
- [Qt教程] 第27篇 XML(一)使用DOM读取XML文档
- 【jq插件】Grade-打分效果
- 关于左移右移的操作 学习
- mysql mssql 性能对比_详解mysql分区实验测试--非分区表与分区表的性能对比
- 51单片机4位抢答器_倒计时可调仿真设计
- C语言冒泡排序(函数版)
- 沙箱 sandbox
- 双网卡(内外网)配置,路由+DNS
- 软件工程——团队作业2
- ios如何解除dns被劫持_iPhone被DNS劫持,老跳广告咋办?
- 【阿里云总监课】存储系统设计——NVMe SSD性能影响因素一探究竟
- 推荐几个程序员Mac m1max芯片笔记本软件
- 洗扑克牌 (乱数排序)
- 剑指offer-丑数(Java)
- 令人愉悦的性能统计分析工具-hiper 【发个copy】
- 拉普拉斯变形的原理解析和python代码
- java sl4j 日志_为Java项目添加slf4j的log日志-阿里云开发者社区
热门文章
- 【机器视觉】 ifelse算子(已废弃)
- S如何边缘控制_如何用尼康佳能索尼人像标头50mm/1.8拍出大片的效果?
- 广东省计算机大赛设计什么时候,2017年广东省大学生计算机设计大赛
- php 中session与cookies的区别,php中session和cookie的区别
- mysql隔离级别 举例_mysql的事务隔离级别举例
- zookeeper快速入门,配置虚拟机ip、mac、虚拟机免密,jdk的安装与卸载
- 合并两个有序数组—leetcode88
- java hashmap 输出_JAVA如何把HashMap内容输出到文本文件
- matlab偶极矩电场强度分布图_物理-电磁学|第三讲|静电场中的电介质
- Delphi程序自删除