FZU 2082 过路费 (树链剖分)边权
来源:互联网 发布:漫画集软件 编辑:程序博客网 时间:2024/05/01 04:39
Problem 2082 过路费
Accept: 322 Submit: 1101
Time Limit: 1000 mSec Memory Limit : 32768 KB
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 31 2 11 1 20 1 21 2 1
Sample Output
12
Source
FOJ有奖月赛-2012年4月(校赛热身赛)解题:一道 裸树的树链剖分
#include<stdio.h>#include<string.h>#define LL __int64const int N = 50005;int head[N<<1],to[N<<1],next1[N<<1],tot;int deep[N],fath[N],son[N],num[N];int top[N],p[N],pos;void init(){ pos=tot=0; memset(head,-1,sizeof(head));}void addEdge(const int& u, const int& v){ to[tot] = v, next1[tot] = head[u], head[u] = tot++;}void addUndirEdge(const int& u, const int& v){ addEdge(u, v), addEdge(v, u);}void dfs1(int u,int pre,int d){ fath[u]=pre; deep[u]=d; son[u]=-1; num[u]=1; for(int i=head[u]; i!=-1; i=next1[i]){ int v=to[i]; if(v==fath[u])continue; dfs1(v,u,d+1); num[u]+=num[v]; if(son[u]==-1||num[v]>num[son[u]]) son[u]=v; }}void getpos(int u,int root){ top[u]=root; p[u]=pos++; if(son[u]==-1) return ; getpos(son[u],root); for(int i=head[u]; i!=-1; i=next1[i]){ int v=to[i]; if(v==son[u]||v==fath[u]) continue; getpos(v,v); }}LL root[N*3],cost[N];void pushUp(int k){ root[k]=root[k<<1]+root[k<<1|1];}void build(int l, int r, int k){ if(l==r){ root[k]=cost[l]; return ; } int mid=(l+r)>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); pushUp(k);}void update(int l, int r, int k, const int& id, LL c){ if(l==r){ root[k]=c; return ; } int mid=(l+r)>>1; if(id<=mid) update(l,mid,k<<1,id,c); else update(mid+1,r,k<<1|1,id,c); pushUp(k);}LL query(int l, int r, int k, const int& L, const int& R){ if(L<=l&&r<=R){ return root[k]; } int mid=(l+r)>>1; LL sum=0; if(L<=mid) sum+=query(l,mid,k<<1,L,R); if(mid<R) sum+=query(mid+1,r,k<<1|1,L,R); return sum;}void swp(int &u,int &v){ int tt=u; u=v; v=tt;}LL solve(int u,int v){ int fu=top[u], fv=top[v]; LL sum=0; while(fu!=fv){ if(deep[fu]<deep[fv]){ swp(fu,fv); swp(u,v); } sum+=query(1,pos,1,p[fu],p[u]); u=fath[fu]; fu=top[u]; } if(u==v)return sum; if(deep[u]>deep[v]) swp(u,v); sum+=query(1,pos,1,p[son[u]],p[v]);//一不小心p[son[u]]写成了p[u]让我WA了好几次(求边权用p[son[u]],求点权用p[u]) return sum;}struct EDG{ int u,v; LL c;}edg[N];int main(){ int n,m,op,a,b; while(scanf("%d%d",&n,&m)>0){ init(); for(int i=1; i<n; i++){ scanf("%d%d%I64d",&edg[i].u,&edg[i].v,&edg[i].c); addUndirEdge(edg[i].u, edg[i].v); } dfs1(1,1,1); getpos(1,1); for(int i=1; i<n; i++){ if(deep[edg[i].u]>deep[edg[i].v]) swp(edg[i].u, edg[i].v); cost[p[edg[i].v]]=edg[i].c; } pos=n; build(1,pos,1); while(m--){ scanf("%d%d%d",&op,&a,&b); if(op==0) update(1,pos,1,p[edg[a].v],b); else printf("%I64d\n",solve(a,b)); } }}
0 0
- FZU 2082 过路费 (树链剖分)边权
- FZU 2082 过路费(树链剖分,边权)
- FZU 2082 过路费(树链剖分)
- fzu 2082 过路费(树链剖分)
- FZU 2082 过路费 (树链剖分)
- FZU 2082 过路费(树链剖分)
- 【树链剖分】 FZU 2082 过路费
- fzu 2082 过路费(树链剖分)
- FZU 2082 过路费 (树链剖分)
- FZU 2082 过路费 树链剖分
- FZU 2082过路费 树链剖分
- FZU 2082 过路费 [树链剖分]
- FZU 2082 过路费(树链剖分+BIT)
- 【树链剖分】FZU 2082 过路费 求和
- 树链刨分 (FZU 2082过路费)
- fzu 2082 过路费(树链剖分,询问两点距离)
- fzu 2082 过路费(树链剖分,单点更新+区间求和)
- FZU 2082 过路费(树链剖分+线段树)
- subplot上标记、画图
- js中的闭包之我理解
- Java数据结构-Map(七)
- (wordpress安装)针对WampServer出现You don't have permission to access /phpmyadmin/ on this server.
- atitit.图片相似度与图片查找的设计 获取图片指纹
- FZU 2082 过路费 (树链剖分)边权
- Atitit.遍历图像像素点rgb java attilax总结
- cocos2dx -- 学习笔记 利用UIButton制作虚拟按键
- 编译并链接pthreads-win32静态库
- 例题3-17(筛选法求素数)
- Java:单例模式的七种写法
- Java之Socket编程实现一对一通信
- LeetCode 11 Container With Most Water (C,C++,Java,Python)
- 归档解档(文件写入与读取)