SPOJ QTREE-Query on a tree-树链剖分-边权
用每个点代表父节点到此点的边。建立一一映射后就可以用点权的方法处理了。
注意的是路径两端节点的处理
#include <cstdio>
#include <algorithm>
#include <vector> using namespace std; const int maxn = 1e5+;
int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn];
int topw,M; vector<int> G[maxn];
struct Edge{
int x,y,val;
}e[maxn]; void dfs_1(int u,int f,int d)
{
fa[u] = f;
son[u] = ;
siz[u] = ;
dep[u] = d; for(int i=;i<G[u].size();i++) if(G[u][i] != f )
{
dfs_1(G[u][i],u,d+);
siz[u] += siz[G[u][i]];
if(siz[son[u] ] < siz[G[u][i] ])
{
son[u] = G[u][i];
}
}
} void dfs_2(int u,int tp)
{
top[u] = tp;
id[u] = ++topw;
if(son[u]) dfs_2(son[u],tp);
for(int i=;i<G[u].size();i++) if(G[u][i] != fa[u] && G[u][i] != son[u])
{
dfs_2(G[u][i],G[u][i]);
}
} int N,T; void debug()
{
for(int i=;i<=N;i++)
{
printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
printf("top:%d id:%d\n",top[i],id[i]);
}
} /*-------------------------------------*/
//segment Tree
#define lson(x) (x<<1)
#define rson(x) (x<<1|1) struct SegmentTree{
int l,r,val;
}sgtree[*maxn]; void pushup(int x)
{
sgtree[x].val = max(sgtree[lson(x)].val,sgtree[rson(x)].val);
} void Build(int l,int r,int x)
{
sgtree[x].l = l;
sgtree[x].r = r;
if(l==r)
{
sgtree[x].val = val[l];
return ;
}
int mid = (l+r)>>;
Build(l,mid,lson(x));
Build(mid+,r,rson(x));
pushup(x);
} void update(int x,int v,int add)
{
if(sgtree[x].l == sgtree[x].r)
{
sgtree[x].val = add;
//printf("change:%d %d\n",v,sgtree[x].l);
return ;
}
int mid = (sgtree[x].l+sgtree[x].r)>>;
if(v <= mid) update(lson(x),v,add);
else update(rson(x),v,add);
pushup(x);
} int query(int x,int l,int r)
{
if(sgtree[x].l >= l && sgtree[x].r <= r)
{
return sgtree[x].val;
}
int mid = (sgtree[x].l+sgtree[x].r)>>;
int ans = ;
if(l <= mid) ans = max(ans,query(lson(x),l,r));
if(r > mid) ans = max(ans,query(rson(x),l,r));
return ans;
} int Find(int u,int v)
{
int ans = ,fu = top[u],fv = top[v];
while(fu != fv)
{
if(dep[fu] < dep[fv])
{
swap(fu,fv);swap(u,v);
}
ans = max(ans,query(,id[fu],id[u]));
u = fa[fu];
fu = top[u];
}
if(u == v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return max(ans,query(,id[son[u] ],id[v]));
} int main()
{
//freopen("input.in","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i=,a,b,c;i<N;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[i].x = a;
e[i].y = b;
e[i].val = c;
G[a].push_back(b);
G[b].push_back(a);
}
topw = ;
dfs_1(,,);
dfs_2(,);
//debug(); for(int i=;i<N;i++)
{
if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y);
val[id[e[i].x]] = e[i].val;
} Build(,topw,);
char op[];
while(scanf("%s",op) && op[] != 'D')
{
int a,b;
scanf("%d%d",&a,&b);
if(op[] == 'Q')
printf("%d\n",Find(a,b));
else if(op[] == 'C')
update(,id[e[a].x],b);
} for(int i=;i<=N;i++) G[i].clear();
}
}
SPOJ QTREE-Query on a tree-树链剖分-边权的更多相关文章
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- spoj 375 Query on a tree (树链剖分)
Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
随机推荐
- dcoker搭建wordpress
下载wordpress镜像 docker pull wordpress 创建wordpress容器 docker run -d --name wordpress --link mysql:mysql ...
- python 获取lazada菲律宾站地址库
import urllib3 import requests import ast import time # 因为lazada返回的数据是json类型,通过解码成字符串类型,为了方便数据操作,使用字 ...
- 容器互联(linking)
容器互联(linking)是一种让多个容器中的应用进行快速交互的方式. 它会在源和接受容器中间创建连接关系,接受容器可以通过容器名快速访问到源容器而不用指出具体的IP地址.
- amd,cmd规范
AMD 和 CMD 的区别有哪些? AMD规范与CMD规范的区别 回顾:前端模块化和AMD.CMD规范(全) 浅析JS模块规范:AMD,CMD,CommonJS 理解AMD ,CMD,CommonJS ...
- Debian搭建WordPress
环境配置 可以使用apt-get快速安装mysql,php5:我是用源码手动安装apache服务器的.安装完mysql后,最好将字符编码设置为utf8的. 接下来就是mysql,apache,php5 ...
- 多线程系列之四:Guarded Suspension 模式
一,什么是Guarded Suspension模式如果执行现在的处理会造成问题,就让执行处理的线程等待.这种模式通过让线程等待来保证实例的安全性 二,实现一个简单的线程间通信的例子 一个线程(Clie ...
- 【学习总结】GirlsInAI ML-diary day-4:变量/Variable
[学习总结]GirlsInAI ML-diary 总 原博github链接-day4 变量/Variable 变量是计算机编程中一个很基础的概念,在计算机程序中,variables are reser ...
- Linux reboot与init 6区别
Reboot与init 6的区别 - flyingcloud_2008的专栏 - CSDN博客https://blog.csdn.net/flyingcloud_2008/article/detail ...
- oracle服务端安装与配置
从oracle官网下载oracle服务端的安装包. 下载下来是两个压缩文件,两个压缩文件都解压(缺一不可)到同一目录下,最后会得到一个database文件夹. 双击database文件夹下的setup ...
- 项目中常用的MySQL 优化
本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我 ...