题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I

给你一棵有边权的树,有两个操作:一个操作是输出l到r点之间的最大的边权,另一个操作是修改某条边的权值。

这题是树链剖分的简单模版题,代码如下:

 //修改单边权
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e4 + ;
struct data {
int next , to , cost;
}edge[MAXN << ];
int head[MAXN] , top[MAXN] , id[MAXN] , par[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN];
int cnt , tot , v[MAXN] , u[MAXN] , cost[MAXN]; void init() {
cnt = tot = ;
memset(head , - , sizeof(head));
} inline void add(int u , int v , int cost) {
edge[cnt].next = head[u];
edge[cnt].to = v;
edge[cnt].cost = cost;
head[u] = cnt++;
} void dfs_1(int u , int p , int d) {
dep[u] = d , par[u] = p , size[u] = , son[u] = u;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dfs_1(v , u , d + );
if(size[son[u]] < size[v])
son[u] = v;
size[u] += size[v];
}
} void dfs_2(int u , int p , int t) {
top[u] = t , id[u] = ++tot;
if(son[u] != u)
dfs_2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p || v == son[u])
continue;
dfs_2(v , u , v);
}
} struct segtree {
int l , r , Max;
}T[MAXN << ]; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r;
if(l == r)
return ;
build(p << , l , mid);
build((p << )| , mid + , r);
} void updata(int p , int pos , int num) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r) {
T[p].Max = num;
return ;
}
if(pos <= mid)
updata(p << , pos , num);
else
updata((p << )| , pos , num);
T[p].Max = max(T[p << ].Max , T[(p << )|].Max);
} int query(int p , int l , int r) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r)
return T[p].Max;
if(r <= mid)
return query(p << , l , r);
else if(l > mid)
return query((p << )| , l , r);
else
return max(query(p << , l , mid) , query((p << )| , mid + , r));
} int Find(int l , int r) {
int pl = top[l] , pr = top[r] , Max = ;
while(pl != pr) {
if(dep[pl] > dep[pr]) {
Max = max(Max , query( , id[pl] , id[l]));
l = par[pl];
pl = top[l];
}
else {
Max = max(Max , query( , id[pr] , id[r]));
r = par[pr];
pr = top[r];
}
}
if(r == l)
return Max;
else if(dep[r] > dep[l])
return max(Max , query( , id[son[l]] , id[r]));
else
return max(Max , query( , id[son[r]] , id[l]));
} int main()
{
int t , n , l , r;
scanf("%d" , &t);
while(t--) {
scanf("%d" , &n);
init();
for(int i = ; i < n ; ++i) {
scanf("%d %d %d" , u + i , v + i , cost + i);
add(u[i] , v[i] , cost[i]);
add(v[i] , u[i] , cost[i]);
}
dfs_1( , , );
dfs_2( , , );
build( , , tot);
for(int i = ; i < n ; ++i) {
if(dep[u[i]] > dep[v[i]])
swap(u[i] , v[i]);
updata( , id[v[i]] , cost[i]);
}
char q[];
while(scanf("%s" , q) && q[] != 'D') {
scanf("%d %d" , &l , &r);
if(q[] == 'C') {
updata( , id[v[l]] , r);
}
else {
printf("%d\n" , Find(l , r));
}
}
}
return ;
}

SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)的更多相关文章

  1. SPOJ 375 树链剖分

    SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...

  2. SPOJ 375 (树链剖分+线段树)

    题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...

  3. SPOJ 375 树链剖分 QTREE - Query on a tree

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  4. spoj 375 树链剖分 模板

    QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...

  5. POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权

    题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作: 0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val   把第 x 条边的权值改为 ...

  6. spoj 375 树链剖分模板

    /* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...

  7. FZU 2082 过路费 (树链剖分 修改单边权)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...

  8. POJ 2763 Housewife Wind (树链剖分 有修改单边权)

    题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...

  9. SPOJ QTREE 树链剖分

    树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...

随机推荐

  1. 使用Quartz创建定时任务

    项目开发中经常需要定时循环执行某些任务 比如定时发送报表,定时发送邮件,亦或者定时清理缓存,定时更新数据等等 有些时候可以简单地利用Windows Server的计划任务执行程序 Linux也有相应的 ...

  2. org.tigris.subversion.javahl.ClientException: Attempted to lock an already-locked dir异常解决方法

    myeclipse用svn提交的时候报错: Attempted to lock an already-locked dir svn: Working copy 'D:/Program Files/My ...

  3. BZOJ_1629_[Usaco2007_Demo]_Cow_Acrobats_(贪心)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1629 \(n\)头牛叠罗汉.第\(i\)头牛的力量为\(s_i\),重量为\(w_i\),危险 ...

  4. HDU 1397 Goldbach's Conjecture【素数打表】

    题意:给出n,问满足a+b=n且a,b都为素数的有多少对 将素数打表,再枚举 #include<iostream> #include<cstdio> #include<c ...

  5. Oracle中使用escape关键字实现like匹配特殊字符,以及&字符的转义

    转:http://blog.chinaunix.net/uid-26896647-id-3433968.html 问题描述:如果在一个表中的一个字段上存在'&',  '_',  '%'这样的特 ...

  6. string.Format 里面包含 javascript方法参数的时候 单引号变成双引号的问题解决方法

    解决方法如下 StringBuilder sb = new StringBuilder(); var str =@"<label><input type='checkbox ...

  7. UVALive 2238 Fixed Partition Memory Management(二分完美匹配)

    题意:计算机中有一些固定大小的内存,内存越大,处理速度越快.对于一个程序,加入不同的内存空间,处理所需时间不同.现给出m个内存空间,n个程序,对于每个程序程序,有k组数据(s,t),分别表示当程序 i ...

  8. Linux likely unlikely

    /************************************************************************* * Linux likely unlikely * ...

  9. Java [Leetcode 155]Min Stack

    题目描述: Design a stack that supports push, pop, top, and retrieving the minimum element in constant ti ...

  10. Java基础——I/O

    文本I/O与二进制I/O 在计算机中所有的文件都是以二进制的形式来存储的,所以本质上所有的文件都是二进制文件. 文本I/O建立在二进制I/O的基础之上,它能提供字符层次的编码和解码的抽象,在写入一个字 ...