POJ 2763 在线lca
来源:互联网 发布:建模软件 编辑:程序博客网 时间:2024/05/06 09:23
链接:http://poj.org/problem?id=2763
题意:n个点构成树,q个询问,每次询问得到树上两点距离。
操作一:问从当前位置(起始在s)到v的距离(每次移动到新的地方)。
操作二:将第i条边的长度改为w
处理出到树根的距离,操作一每次用lca求dis[s] + dis[t] - 2*dis[lca(s,t)];操作二,更新某条边之后对这条边下面的子树到树根的距离更新。
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;#define mem(a,b) memset((a),(b),sizeof((a)))#define For(i,a,b) for(int (i)=(a);(i) < (b);(i)++)#define Ror(i,a,b) for(int (i)=(a);(i) > (b);(i)--)#define mp make_pair#define pb push_back#define inf 0x3f3f3f3fvoid RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x;}void RII (int& x, int& y){RI (x), RI (y);}void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}const int maxn = 200010;const int maxm = 200010;struct Side { int v,w,next;}side[maxm];int top,node[maxn];void add_side(int u,int v,int w){ side[top] = (Side){v,w,node[u]}; node[u] = top++;}int ver[maxn];int r_min[maxn][20];int first[maxn],dis[maxn],R[maxn];//R深度int tt;void ST(int n){ for(int i=1;i<=n;i++){ r_min[i][0]=i; } int k=log((double)(n+1))/log(2.0); for(int j=1;j<=k;j++){ for(int i=1;i+(1<<j)-1<=n;i++){ int a = r_min[i][j-1],b = r_min[i+(1<<(j-1))][j-1]; r_min[i][j] = R[a] < R[b] ? a : b; } }}int RMQ(int l,int r){ int k=log((double)(r-l+1))/log(2.0); int a = r_min[l][k],b = r_min[r-(1<<k)+1][k]; return R[a] < R[b] ? a : b;}int lca(int a,int b){ a = first[a]; b = first[b]; if(a > b)swap(a,b); int ans = RMQ(a,b); return ver[ans];}void dfs(int u,int dep){ ver[++ tt] = u;first[u] = tt;R[tt] = dep; for(int i = node[u];i != -1;i = side[i].next){ int v = side[i].v; if(first[v] == 0){ dis[v] = dis[u] + side[i].w; dfs(v,dep+1); ver[++ tt] = u;R[tt] = dep; } }}struct BB{ int s,t;}bb[maxm];void do_chg(int ss,int fa,int cc){ dis[ss] += cc; for(int i = node[ss];i != -1;i = side[i].next){ int v = side[i].v; if(v != fa)do_chg(v,ss,cc); }}void change(int fa,int son,int w){ if(dis[fa] > dis[son])swap(fa,son);//cout<<fa<<' '<<son<<endl; int cc; for(int i = node[fa];i != -1;i = side[i].next){ int v = side[i].v; if(v == son){ cc = w - side[i].w; side[i].w = w; break; } } do_chg(son,fa,cc);}int main(){ //freopen("test.txt","r",stdin); int n,q,s; while(~scanf("%d%d%d",&n,&q,&s)){ mem(node,-1);top = 0; For(i,0,n-1){ int a,b,c; RIII(a,b,c); add_side(a,b,c); add_side(b,a,c); bb[i+1] = (BB){a,b}; } mem(first,0); tt = 0;dis[1] = 0; dfs(1,1); ST(2*n-1); while(q --){ int op; RI(op); switch(op){ case 0:{ int t; RI(t); cout<<dis[s] + dis[t] - 2*dis[lca(s,t)]<<endl; //cout<<"fa:"<<lca(first[s],first[t])<<endl; s = t; break; } case 1:{ int i,w; RII(i,w); change(bb[i].s,bb[i].t,w); break; } } } } return 0;}
0 0
- POJ 2763 在线lca
- POJ 1986 Distance Queries(在线LCA)
- POJ 1330 Nearest Common Ancestors 在线LCA
- LCA模板在线 POJ 1986 Distance Queries
- POJ 2763 LCA+BIT
- poj 2763 LCA
- 在线LCA
- 【POJ】1330 Nearest Common Ancestors 在线LCA,倍增思想
- POJ 1330 Nearest Common Ancestors (在线LCA转RMQ)
- POJ 1470 Closest Common Ancestors (在线LCA转RMQ)
- POJ 1986 Distance Queries (在线LCA转RMQ)
- POJ 1986 - Distance Queries(LCA‘ 在线算法RMQ)
- POJ 1330 ---(线段树在线LCA 与 tarjan离线LCAs)
- POJ - 1330 Nearest Common Ancestors(LCA在线查询)
- POJ 3417 Network(在线倍增LCA+树形DP)
- POJ 1330 Nearest Common Ancestors(在线倍增LCA)
- poj 1330 Nearest Common Ancestors lca rmq在线算法
- POJ 1470 Closet Conmon Ancestors(LCA在线算法)
- 3. jQuery 选择器
- 从线性模型到广义线性模型(2)——参数估计、假设检验
- torshammer
- include h 和include 。c的区别
- 有些数的素因子只有3,5,7.请设计一个算法,找出其中第k个数
- POJ 2763 在线lca
- 3 Layer and 3 Tier
- 二叉排序树
- sql扫盲(4)
- 【每天一个Linux命令】25. 查看文件命令(cat/more/less/tail/tac/nl/od)
- Mysql中类似于nvl()函数的ifnull()函数
- 002—交叉工具链与使用
- hdu1249三角形(递推)
- cornerHarris函数