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 ...
随机推荐
- 分享一个公众号h5裂变吸粉源码工具
这次我是分享我本人制作的一个恶搞程序,说白了就是一个公众号裂变吸粉工具,市面上有很多引流方法,例如最常见的就是色流,哈哈,今天我跟大家分享的方法是有趣的,好玩的,恶搞的.这个程序上线一天已经收获了61 ...
- rest_framework之视图及源码剖析
最初形态(工作中可能会使用) 引子 Django的CBV我们应该都有所了解及使用,大体概括一下就是通过定义类并在类中定义get post put delete等对应于请求方法的方法,当请求来的时候会自 ...
- hibernate坑边闲话
使用hibernate各种各样的坑 Remember that ordinal parameters are 1-based node to traverse cannot be null 这两个错误 ...
- Servlet 使用ServletContext共享数据,读取web.xml配置
ServletContext对象 session和cookie,对于每一个请求用户来说,都是不同的,因为要保证隐私安全. 而有一些数据,可以让所有用户共享,此时就可以用ServletContext对象 ...
- mysql备份(导出)数据库,并恢复数据
导出某个数据库数据到文件中 假设要导出test这个数据库,那么可以在Linux命令行(不是在mysql中) [root@ubuntu /data]# mysqldump -uroot -p test ...
- redux模块化demo
store.js 在redux中 store 是唯一的. import {createStore} from 'redux'; import reducer from './reducer' // 引 ...
- Auzre系列1.1.1 —— 安装用于 IntelliJ 的 Azure 工具包
(文中大部分内容(95%)Azure官网上有,我只是把我自己实际操作中遇到的问题在这里阐述一下.) 先决条件 若要完成文章中的步骤,需要安装用于 IntelliJ 的 Azure 工具包,该工具包需要 ...
- [转帖]震惊,用了这么多年的 CPU 利用率,其实是错的
震惊,用了这么多年的 CPU 利用率,其实是错的 2018年12月22日 08:43:09 Linuxer_ 阅读数:50 https://blog.csdn.net/juS3Ve/article/d ...
- [2018.05].NET Core 3 and Support for Windows Desktop Applications
.NET Core 3 and Support for Windows Desktop Applications Richard 微软官网的内容...net 3.0 升级任务 任重道远 https:/ ...
- Day 4-1 模块的导入方法和路径
什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码 ...