Problem 2082 过路费

Problem Description

有n座城市,由n-1条路相连通,使得任意两座城市之间可达。每条路有过路费,要交过路费才能通过。每条路的过路费经常会更新,现问你,当前情况下,从城市a到城市b最少要花多少过路费。

Input

有多组样例,每组样例第一行输入两个正整数n,m(2 <= n<=50000,1<=m <= 50000),接下来n-1行,每行3个正整数a b c,(1 <= a,b <= n , a != b , 1 <= c <= 1000000000).数据保证给的路使得任意两座城市互相可达。接下来输入m行,表示m个操作,操作有两种:一. 0 a b,表示更新第a条路的过路费为b,1 <= a <= n-1 ; 二. 1 a b , 表示询问a到b最少要花多少过路费。

Output

对于每个询问,输出一行,表示最少要花的过路费。

 Sample Input

2 3
1 2 1
1 1 2
0 1 2
1 2 1

 Sample Output

1 2
 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = ;
int son[maxn]; //表示该点重链的子节点
int num[maxn]; //表示以该点为根的子树的节点数量
int dep[maxn]; //表示该节点的深度
int fa[maxn]; // 表示该节点的父亲节点
int vis[maxn]; // 表示该节点在线段树中的编号
int top[maxn]; // 表示这条重链的顶端节点
int is[maxn];
int edge[maxn][];
int now;
struct Tree
{
int l;
int r;
int Sum;
} tree[maxn*];
struct node
{
int to,val;
} p;
vector<node>E[maxn];
void init()
{
now=;
memset(is,,sizeof(is));
memset(son,-,sizeof(son));
memset(tree,,sizeof(tree));
for(int i=; i<maxn; i++)
E[i].clear();
}
void dfs1(int u,int v,int step) //第一遍dfs求出son,fa,num,dep
{
is[v]=;
dep[v]=step;
num[v]=;
fa[v]=u;
int len = E[v].size();
for(int i=; i<len; i++)
{
int to = E[v][i].to;
if(!is[to])
{
dfs1(v,to,step+);
num[v]+=num[to];
if(son[v]==-||num[son[v]]<num[to])
{
son[v]=to;
}
}
}
return ;
}
void dfs2(int u,int v) // 第二遍dfs求出top和vis
{
is[v]=;
top[v]=u;
vis[v]=now++;
if(son[v]==-)
return ;
else
dfs2(u,son[v]);
int len = E[v].size();
for(int i=; i<len; i++)
{
int to = E[v][i].to;
if(!is[to])
{
if(to==fa[v]||to==son[v])
continue;
dfs2(to,to);
}
}
}
void build(int v,int l,int r)
{
tree[v].l=l;
tree[v].r=r;
if( l == r )
{
tree[v].Sum=;
return;
}
int mid=( l+r )>>;
build( v<<,l,mid );
build( v<<|,mid+,r );
tree[v].Sum=;
}
int query( int v,int l,int r)
{
if (l==tree[v].l&&r==tree[v].r)
return tree[v].Sum;
int mid=(tree[v].l+tree[v].r)>>;
if(l <= mid && r <= mid)
return query(v<<,l,r);
else if(l > mid)
return query(v<<|,l,r);
else
return query(v<<,l,mid)+query(v<<|,mid+,r);
}
void update(int v,int x,int m)
{
int l,r;
l = tree[v].l;
r = tree[v].r;
int mid = (l + r) / ;
if(l == r)
{
tree[v].Sum = m;
return;
}
if(x <= mid)
update(v<<,x,m);
else
update(v<<|,x,m);
tree[v].Sum=query(v<<,l,mid)+query(v<<|,mid+,r);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=; i<=n-; i++)
{
scanf("%d%d%d",&edge[i][],&edge[i][],&edge[i][]);
p.to=edge[i][],p.val=edge[i][];
E[edge[i][]].push_back(p);
p.to=edge[i][],p.val=edge[i][];
E[edge[i][]].push_back(p);
}
dfs1(,,);
memset(is,,sizeof(is));
dfs2(,);
build(,,n);
for(int i = ; i <= n-; i++)
{
if(dep[edge[i][]] < dep[edge[i][]])
swap(edge[i][],edge[i][]);
update(,vis[edge[i][]]+,edge[i][]);
}
while(m--)
{
int x,y,z,q,w;
scanf("%d%d%d",&x,&y,&z);
if(x)
{
q = top[y],w = top[z];
int ans = ;
while(q != w) //不在一条重链上,就爬树
{
if(dep[q] < dep[w])
{
swap(q,w);
swap(y,z);
}
ans += query(,vis[q]+,vis[y]+);
y = fa[q];
q = top[y];
}
if(y != z) //爬到一条重链上
{
if(dep[y] > dep[z])
swap(y,z);
ans += query(,vis[son[y]]+,vis[z]+);
}
printf("%d\n",ans);
}
else
{
update(,vis[edge[y][]]+,z);
}
} }
return ;
}

FZU oj Problem 2082 过路费的更多相关文章

  1. Fzu Problem 2082 过路费 LCT,动态树

    题目:http://acm.fzu.edu.cn/problem.php?pid=2082 Problem 2082 过路费 Accept: 528    Submit: 1654Time Limit ...

  2. FZU Problem 2082 过路费 树链剖分

    Problem 2082 过路费    Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新, ...

  3. FZU Problem 2082 过路费

    Problem 2082 过路费 Accept: 875    Submit: 2839Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem ...

  4. FOJ题目Problem 2082 过路费 (link cut tree边权更新)

    Problem 2082 过路费 Accept: 382    Submit: 1279 Time Limit: 1000 mSec    Memory Limit : 32768 KB Proble ...

  5. fzu 2082 过路费 (树链剖分+线段树 边权)

    Problem 2082 过路费 Accept: 887    Submit: 2881Time Limit: 1000 mSec    Memory Limit : 32768 KB  Proble ...

  6. FZU 2082 过路费(树链剖分)

    FZU 2082 过路费 题目链接 树链抛分改动边的模板题 代码: #include <cstdio> #include <cstring> #include <vect ...

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

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

  8. FZU 2082 过路费(树链剖分)

    树链剖分模板题. FZU炸了,等交上去AC了再贴代码.

  9. FZU 2082 过路费

    树链剖分模板题 #include <cstdio> #include <iostream> #include <cstring> #include <algo ...

随机推荐

  1. 常用GDB命令行调试命令

    po po是print-object的简写,可用来打印所有NSObject对象.使用举例如下: (gdb) po self <LauncherViewController: 0x552c570& ...

  2. Rust写时复制Cow<T>

    写时复制(Copy on Write)技术是一种程序中的优化策略,多应用于读多写少的场景.主要思想是创建对象的时候不立即进行复制,而是先引用(借用)原有对象进行大量的读操作,只有进行到少量的写操作的时 ...

  3. 10个常用的linux的命令

    以下就是今天我们要介绍的Linux命令:  man  touch, cat and less  sort and grep  cut  sed  tar  find  diff  uniq  chmo ...

  4. 荔枝FM前端面试题

    最近接到了荔枝FM的面试通知,遗憾的是没有拿到offer,但是这次面试呢,还是收获很大的,下面就来给大家说说我遇到的面试题 一面 一面是直接发了一套面试题到邮箱,开启了防作弊的,限时20分钟做完,下面 ...

  5. AndroidSDK的目录详解

    Tools 目录工具(必须的工具) Android SDK Tools(必须,只需下载一个版本,一般选最新版本):基础工具包,版本号带rc字样的是预览版. Android SDK Platform-t ...

  6. SpringBoot 集成Jedis操作set

    题外话: Redis是个有趣的东西,相信搞java的或多或少都会用到,面试时也总离不开问Redis,之前觉得redis只是用做缓存,飞快!也因为最初在封装底层的时候,使用Redisson,所以大部分都 ...

  7. golang 结合实例更好的理解参数传递和指针

    关于参数传递 其实go的参数传递,核心就是一句话:go里所有参数传递都是值传递,既把参数复制一份放到函数里去用. go的函数传参,不管参数是什么类型,都会复制一份,然后新的参数在函数内部被使用. 不像 ...

  8. JavaMail的简单使用(自测可以发邮件)

    在很多项目中我们都会遇到发送邮件的功能,发送邮件其实还是很实用的,正好今天做项目需要实现,现在来简单的整理一下发送邮件的实现. 建立邮件与服务器之间的会话 Properties props = new ...

  9. ZooKeeper系列(二)—— Zookeeper 单机环境和集群环境搭建

    一.单机环境搭建 1.1 下载 下载对应版本 Zookeeper,这里我下载的版本 3.4.14.官方下载地址:https://archive.apache.org/dist/zookeeper/ # ...

  10. 普通Apache的安装与卸载

    Apache安装与卸载ctrl+F快捷查找 1.下载apache 64位解压 官网:http://httpd.apache.org/ 文件使用记事本或者sublime2.修改 打开apache目录下的 ...