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

Problem 2082 过路费

Accept: 382    Submit: 1279
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月(校赛热身赛) 

ac代码

RunID: 628735
UserID: kxh1995_joker
Submit time: 2015-08-17 18:05:24
Language: C++
Length: 2884 Bytes.
Result: Accepted

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<iostream>
using namespace std;
int head[50050],cnt,vis[50050];
struct s
{
	int u,v,w,next;
}edge[50050<<1];
struct LCT  
{  
    int bef[50050],pre[50050],next[50050][2],key[50050],sum[50050],belong[50050];
    void init()  
    {  
        memset(pre,0,sizeof(pre));
        memset(next,0,sizeof(next));  
    }
	void pushup(int x)
	{
		sum[x]=key[x]+sum[next[x][1]]+sum[next[x][0]];
	}
    void rotate(int x,int kind)  
    {  
        int y,z;  
        y=pre[x];  
        z=pre[y];  
        next[y][!kind]=next[x][kind];  
        pre[next[x][kind]]=y;  
        next[z][next[z][1]==y]=x;  
        pre[x]=z;  
        next[x][kind]=y;  
        pre[y]=x;
		pushup(y);
    }  
    void splay(int x)  
    {  
        int rt;  
        for(rt=x;pre[rt];rt=pre[rt]);  
        if(x!=rt)  
        {  
            bef[x]=bef[rt];  
            bef[rt]=0;  
            while(pre[x])  
            {  
                if(next[pre[x]][0]==x)  
                {  
                    rotate(x,1);  
                }  
                else  
                    rotate(x,0);  
            }  
			pushup(x);
        }  
    } 
    void access(int x)  
    {  
        int fa;  
        for(fa=0;x;x=bef[x])  
        {  
            splay(x);  
            pre[next[x][1]]=0;  
            bef[next[x][1]]=x;  
            next[x][1]=fa;  
            pre[fa]=x;  
            bef[fa]=0;  
            fa=x;  
			pushup(x);
        }  
    }
	void change(int x,int val)
	{
		int t;
		t=belong[x-1];
		key[t]=val;
		splay(t);
	}
	int query(int x,int y)
	{
		access(y);
		for(y=0;x;x=bef[x])
		{
			splay(x);
			if(!bef[x])
				return sum[y]+sum[next[x][1]];
			pre[next[x][1]]=0;
			bef[next[x][1]]=x;
			next[x][1]=y;
			pre[y]=x;
			bef[y]=0;
			y=x;
			pushup(x);
		}
	}
}lct;
void add(int u,int v,int w)
{
	edge[cnt].u=u;
	edge[cnt].v=v;
	edge[cnt].w=w;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
void bfs(int u)
{
	int i,y;
	queue<int>q;
	memset(vis,0,sizeof(vis));
	vis[u]=1;
	q.push(u);
	while(!q.empty())
	{
		u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			if(!vis[v])
			{
				lct.bef[v]=u;
				lct.key[v]=lct.sum[v]=edge[i].w;
				lct.belong[i>>1]=v;
				vis[v]=1;
				q.push(v);
			}
		}
	}
}
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int i;
		memset(head,-1,sizeof(head));
		cnt=0;
		for(i=1;i<n;i++)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			add(a,b,c);
			add(b,a,c);
		}
		lct.init();
		bfs(1);
		while(m--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			if(a==0)
			{
				lct.change(b,c);
			}
			else
				printf("%d\n",lct.query(b,c));
		}
	}
}


posted @ 2017-06-23 10:23  lytwajue  阅读(139)  评论(0编辑  收藏  举报