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 ...
随机推荐
- 如果IBM再给我一次实习机会
2014年,我拿到了IBM斯图加特R&D的实习机会.在连续被索尼和博世拒掉之后,这个实习对我来说弥足珍贵.我学的是通信专业,在这之前与编程相关的活动只有一学期的安卓Lab,还是靠抱队友大腿才及 ...
- List,DataTable实现行转列的通用方案
最近在做报表统计方面的需求,涉及到行转列报表.根据以往经验使用SQL可以比较容易完成,这次决定挑战一下直接通过代码方式完成行转列.期间遇到几个问题和用到的新知识这里整理记录一下. 阅读目录 问题介绍 ...
- ECS上配置FTP Filezilla
又来搞华为ECS 第一,服务器安装服务端 第二,设置被动模式,把服务器的公网IP填好 第三,生成一个服务器证书,客户端连接时接受 第四,设置自定义的被动连接端口比如 9000-9050 第五,去ECS ...
- logstash安装及基础入门
Logstash是一款开源的数据收集引擎,具备实时管道处理能力.简单来说,logstash作为数据源与数据存储分析工具之间的桥梁,结合 ElasticSearch以及Kibana,能够极大方便数据的处 ...
- Tomcat搭建Web 应用服务器
和安卓联合开发,测试手机设配效果,被安卓开发大神同事一顿鄙视之后,愤然而起自己搭建了一个本地服务器(愤怒 玻璃心使我成长~哈哈) java+tomcat安装 java安装 注册oracle账号: 手机 ...
- NFV论文集(二)
一 文章名称:VNF Placement with Replication for Load Balancing in NFV Networks 发表时间:2017 期刊来源:ICC: IEEE In ...
- Linux下破解pycharm
1.下载 https://pan.baidu.com/s/119UO4SGIEW_cxf0LmZzx3w 并将 JetbrainsCrack-3.1-release-enc.jar 放置到 pycha ...
- 【学习总结】C-翁恺老师-入门-第3周<循环>
[学习总结]C-翁恺老师-入门-总 1-求一个整数的位数:引入循环while 注:循环体内要有改变循环的机会,要不然就死循环了啊! 注:手写推测程序是否正确. 注:测试程序-边界:个位数.10.0.负 ...
- [转帖]Ipvsadm参数详解(常用命令)
Ipvsadm参数详解(常用命令) 2013年11月29日 12:41:40 怀素1980 阅读数:15901 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
- day 7-16 单表查询
一.准备工作 先把表建立好,方便一会查询. create table emp( id int not null unique auto_increment, name varchar(20) not ...