FZU

来源:互联网 发布:网络实名制 郭德纲 编辑:程序博客网 时间:2024/04/26 16:39

 Problem 2082 过路费

Accept: 830    Submit: 2661
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


思路:树链剖分。

#include<iostream>#include<vector>#include<cstdio>#include<algorithm>using namespace std;const int MAX=1e5;vector<int>e[MAX];struct data{long long x,y,z;}edg[MAX];int fa[MAX],son[MAX],d[MAX],siz[MAX],top[MAX],num[MAX],all;long long val[MAX];void dfs1(int k,int f,int dep){    d[k]=dep;    son[k]=0;    fa[k]=f;    siz[k]=1;    for(int i=0;i<e[k].size();i++)    {        if(e[k][i]==f)continue;        dfs1(e[k][i],k,dep+1);        siz[k]+=siz[e[k][i]];        if(siz[son[k]]<siz[e[k][i]])son[k]=e[k][i];    }}void dfs2(int k,int tp){    num[k]=++all;    top[k]=tp;    if(son[k])dfs2(son[k],tp);    for(int i=0;i<e[k].size();i++)    {        if(e[k][i]==son[k]||e[k][i]==fa[k])continue;        dfs2(e[k][i],e[k][i]);    }}struct lenka{    int l,r;    long long sum;}A[MAX<<2];void build(int k,int l,int r){    A[k].l=l,A[k].r=r;    if(l==r){A[k].sum=val[l];return;}    build(2*k,l,(l+r)/2);    build(2*k+1,(l+r)/2+1,r);    A[k].sum=A[2*k].sum+A[2*k+1].sum;}void change(int k,int x,long long y){    if(x==A[k].l&&x==A[k].r){A[k].sum=y;return;}    if(x<=A[2*k].r)change(2*k,x,y);    else change(2*k+1,x,y);    A[k].sum=A[2*k].sum+A[2*k+1].sum;}long long ask(int k,int x,int y){    if(x==A[k].l&&y==A[k].r)return A[k].sum;    if(y<=A[2*k].r)return ask(2*k,x,y);    else if(x>=A[2*k+1].l)return ask(2*k+1,x,y);    return ask(2*k,x,A[2*k].r)+ask(2*k+1,A[2*k+1].l,y);}long long QWQ(int x,int y){    long long ans=0;    while(top[x]!=top[y])    {        if(d[top[x]]<d[top[y]])swap(x,y);        ans+=ask(1,num[top[x]],num[x]);        x=fa[top[x]];    }    if(x==y)return ans;    if(d[x]>d[y])swap(x,y);    return ans+ask(1,num[son[x]],num[y]);}int main(){    int n,m;    while(cin>>n>>m)    {        for(int i=1;i<=n;i++)e[i].clear();        for(int i=1;i<n;i++)        {            scanf("%lld%lld%lld",&edg[i].x,&edg[i].y,&edg[i].z);            e[edg[i].x].push_back(edg[i].y);            e[edg[i].y].push_back(edg[i].x);        }        all=0;        dfs1(1,0,1);        dfs2(1,1);        for(int i=1;i<n;i++)        {            if(d[edg[i].x]<d[edg[i].y])swap(edg[i].x,edg[i].y);            val[num[edg[i].x]]=edg[i].z;        }        build(1,1,all);        while(m--)        {            int op,x,y;            scanf("%d%d%d",&op,&x,&y);            if(op==0)change(1,num[edg[x].x],y);            else printf("%lld\n",QWQ(x,y));        }    }    return 0;}



原创粉丝点击