题目链接: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. 栈中的push实现

  2. POJ 3090 (欧拉函数) Visible Lattice Points

    题意: UVa 10820 这两个题是同一道题目,只是公式有点区别. 给出范围为(0, 0)到(n, n)的整点,你站在原点处,问有多少个整点可见. 对于点(x, y), 若g = gcd(x, y) ...

  3. POJ 1088 滑雪【记忆化搜索】

    题意:给出一个二维矩阵,要求从其中的一点出发,并且当前点的值总是比下一点的值大,求最长路径 记忆化搜索,首先将d数组初始化为0,该点能够到达的路径长度保存在d数组中,同时把因为路径是非负的,所以如果已 ...

  4. [反汇编练习] 160个CrackMe之018

    [反汇编练习] 160个CrackMe之018. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  5. ubuntu - chrome 标题栏, 书签乱码 解决

    只要修改/etc/fonts/conf.d/49-sansserif.conf这个文件就行了—— 打开/etc/fonts/conf.d/49-sansserif.conf这个文件: sudo ged ...

  6. Java [Leetcode 337]House Robber III

    题目描述: The thief has found himself a new place for his thievery again. There is only one entrance to ...

  7. zoj 1967 Fiber Network/poj 2570

    题意就是 给你 n个点 m条边 每条边有些公司支持 问 a点到b点的路径有哪些公司可以支持 这里是一条路径中要每段路上都要有该公司支持 才算合格的一个公司// floyd 加 位运算// 将每个字符当 ...

  8. css的框架——global.css

    global.css,一般这个css文件是用于装全站主要框架css样式代码. “global”翻译为全局.全部.从翻译中大家也能理解global.css用于做什么.大站常常用于装全站公共的CSS样式选 ...

  9. Corn Fields(POJ 3254状压dp)

    题意: n*m网格1能放0不能放 放的格子不能相邻 求一共多少种可放的方案. 分析: dp[i][j]第i行可行状态j的的最大方案数,枚举当前行和前一行的所有状态转移就行了(不放牛也算一种情况) #i ...

  10. firebug console使用

    Firebug内置一个console对象,提供5种方法,用来显示信息. console.log("Hello World") console.info("这是info&q ...