SPOJ VJudge QTREE - Query on a tree
| Time Limit: 851MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
- CHANGE i ti : change the cost of the i-th edge to ti
or - QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000),
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
- The next lines contain instructions "CHANGE i ti" or "QUERY a b",
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "QUERY" operation, write one integer representing its result.
Example
Input:
1 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE Output:
1
3
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct edge{
int u,v,w,next;
}e[];
struct node{
int l,r,val;
node *lc,*rc;
}*root=NULL;
int t,n,m,head[],js,p;
int fa[],son[],dep[],top[],pos[],siz[];
// fa存他的父亲 son存他的重孩子 dep它的深度 top他所在重链的链顶
//pos在线段树中的位置 siz[v]以v为顶的子树的孩子数
void memsett()
{
js=;p=;
memset(head,,sizeof(head));
memset(e,,sizeof(e));
memset(son,,sizeof(son));
}
void add_edge(int u,int v,int w)
{
e[++js].u=u;e[js].v=v;e[js].w=w;
e[js].next=head[u];head[u]=js;
}
void dfs(int u,int f,int d)
{
fa[u]=f;dep[u]=d;siz[u]=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f)
{
dfs(v,u,d+);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
void gettop(int u,int tp)
{
top[u]=tp;pos[u]=++p;
if(!son[u]) return;
gettop(son[u],tp);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=son[u]&&v!=fa[u])
gettop(v,v);
}
}
void build(node * &pt,int l,int r)
{
pt=new(node);
pt->l=l;pt->r=r;pt->val=;
if(l==r)
{
pt->lc=pt->rc=NULL;
return ;
}
int mid=(l+r)/;
build(pt->lc,l,mid);
build(pt->rc,mid+,r);
}
void update(node * p,int ps,int val)
{
if(p->l==p->r)
{
p->val=val;return;
}
int mid=(p->l+p->r)/;
if(ps<=mid) update(p->lc,ps,val);
else update(p->rc,ps,val);
p->val=max(p->lc->val,p->rc->val);
}
int query(node * p,int l,int r)
{
if(l<=p->l&&p->r<=r)return p->val;
int mid=(p->l+p->r)/;
int ans=;
if(l<=mid)ans=max(ans,query(p->lc,l,r));
if(r>mid)ans=max(ans,query(p->rc,l,r));
return ans;
}
int find(int u,int v)
{
int tp1=top[u],tp2=top[v],ans=;
while(tp1!=tp2)
{
if(dep[tp1]<dep[tp2])
{
swap(tp1,tp2);swap(u,v);
}
ans=max(ans,query(root,pos[tp1],pos[u]));
u=fa[tp1];tp1=top[u];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return max(ans,query(root,pos[u]+,pos[v]));
}
int main()
{
scanf("%d",&t);
while(t--)
{
memsett();
scanf("%d",&n);
for(int i=;i<=n-;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);add_edge(y,x,z);
}
dfs(,,);
gettop(,);
build(root,,p);
for(int i=;i<*n-;i+=)// 建边表时见了两遍
{
if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u);// 让v在下面
update(root,pos[e[i].v],e[i].w);
}
char s[];int u,v;
while(scanf("%s",s)==)
{
if(s[]=='D') break;
scanf("%d%d",&u,&v);
if(s[]=='Q') printf("%d\n",find(u,v));// 查询从u到v所经过的最大边权
else update(root,pos[e[u*-].v],v);// 将第u条边的权值修改为v
}
}
return ;
}
思路:树链剖分基础题
SPOJ VJudge QTREE - Query on a tree的更多相关文章
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ 375 QTREE - Query on a tree
思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...
- 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 ...
- QTREE - Query on a tree
QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...
- SP375 QTREE - Query on a tree (树剖)
题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...
- 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 QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
随机推荐
- #error和#line使用分析
#error的用法 #error用于生成一个编译错误消息 用法:error message(不需要用双引号包围) #error编译指示字用于自定义程序员特有的编译错误,消息类似的 #warning用于 ...
- EOS Dapp体验报告
EOS Dapp体验报告 EOS通过并行链和DPOS的方式解决了延迟和数据吞吐量的难题. EOS能够实现每秒百万级的处理量,而目前比特币是每秒7笔,以太坊是30-40笔,EOS的这一超强能力吊打比特币 ...
- 华为S3700交换机DHCP 配置
1.设置交换机名称 system-view [Huawei]sysname dhcp01 [dhcp01] 2.配置管理IP [dhcp01]interface Vlanif 1 [dhcp01-Vl ...
- js 数组过滤 filter
let res = this.list.filter(item => routeEqual(this.currentRouteObj, item) || item.name === this.$ ...
- Windows下使用ffmpeg与java实现截取视频缩略图
[ffmpeg.exe可执行文件获取]: 网上搜索后得到编译好的ffmpeg文件,下载地址:http://download.csdn.net/source/453719 [安装]: 将下载的文件解压, ...
- JavaSE-28 hashCode()方法、equals()方法和==相关概念
概述 Java中,Object类是所有类的基类:如果一个类没有明确继承其他已定义的类,则默认继承Object类. Object类提供了以下方法,对于其他方法,请参考前期专题描述. hashCode() ...
- Spring-01 注解实现IOC
Spring框架四大原则 使用pojo进行轻量级和最小侵入式开发. 通过依赖注入和基于接口编程实现松耦合. 使用AOP和默认习惯进行声明式编程. 使用AOP和模板(template)减少模式化代码. ...
- 《BUG创造队》作业8:软件测试与Alpha冲刺(第四天)
项目 内容 这个作业属于哪个课程 2016级软件工程 这个作业的要求在哪里 实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 BUG创造队 作业学习目标 (1)掌握软件测试基础技术.(2)学习 ...
- js 简单制作键盘模拟
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head& ...
- 剑指Offer整理笔记
说在前面,本篇的目的是为了学习剑指offer,以及博客园的排版功能,并将文章排版得整洁得体. 梵蒂冈梵蒂冈地方官方