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 ...
随机推荐
- VC++编译出错:LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
解决方法: 1.搜索C盘下的cvtres.exe,结果得到类似这样的列表: C:\Program Files\Microsoft Visual Studio 10.0\VC\bin C:\Window ...
- centos 6.2用yum安装中文输入法
centos 6.2用yum安装中文输入法 1.su root 2.yum install "@Chinese Support" 3.exit 4.回到桌面,system-> ...
- 一段字符串中间提取json字符串
项目过程中经常打日志:LOG.error("[failure][CreateOrder] param:{}", JSON.toJSONString(userCreateOrderD ...
- pspad的一个怪现象:在一些空行的位置出现个别不该出现的字符
在用pspad编辑一个外来文件时,发现有许多空行的结尾会出现一些单个字符,字符内容与翻页前那一页相应位置的字符相同. 好奇怪.上网找不到原因.pspad太好用了,不想因此放弃. 仔细观察,这些空行往往 ...
- 算法之A星算法(寻路)
1.启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省略大量无谓的搜索路径,提高了效率.在启发式搜索中,对位置的估价是十分 ...
- 你的项目刚刚启动?是时候考虑Globalization了!
今天继续由SAP成都研究院非典型程序猿, 菜园子小哥王聪给大家带来分享. 关于这个很长的定语的由来,请参考这篇文章,里面有王聪的背景介绍,包括他种菜的特长:当我用UI5诊断工具时我用些什么. 秋天到了 ...
- pickle 两个使用小方法
def pickle_load(file_path): f = open(file_path,'r+') data = pickle.load(f) f.close() return data ...
- DBMS的工作模式
数据库管理系统(DBMS)是指数据库系统中对数据进行管理的软件系统,它是数据库系统的核心组成部分,对数据库的一切操作(增删改查)都是通过DBMS进行的 DBMS的工作模式如下: 1>接受应用程序 ...
- fgetpos, fseek, fsetpos, ftell, rewind - 重定位某个流
总览 (SYNOPSIS) #include <stdio.h> int fseek(FILE *stream, long offset, int whence); long ftell( ...
- Mapping (RESOURCE) not found :和BeanFactory not initialized or already closed - call 'refresh' before access记录
1.Mapping (RESOURCE) not found :cn/sxx/model/Supplier.hbm.xml : origin(cn/sxx/model/Supplier.hbm.xml ...