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)); } } }