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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为荣耀畅玩6a内存不够怎么办 红米note4玩王者荣耀卡怎么办 华为荣耀5a手机被锁怎么办 华为荣耀v8应用锁忘记蜜码怎么办 阿里巴巴一键代销被投诉受假怎么办 登录小米云服务怎么删除密码怎么办 苹果6云空间连接不上怎么办 买家收到淘宝网交易异常通知怎么办 快递把我秒杀的货弄丢了怎么办 手机淘宝退货物流单号填错了怎么办 买家要求退货退款但是不发货怎么办 多给买家寄包裹不接电话怎么办 给买家发货物流单号错了怎么办 淘宝退货退款快递单号填错了怎么办 淘宝不小心点了延迟收货怎么办 淘宝快递地址错了货已经发了怎么办 卖家送运费险买家填错单号怎么办 买家无赖点了延迟收货卖家怎么办 淘宝卖家快递单号填错了怎么办 淘宝店有当天的快递忘记发货怎么办 在美国官网买东西少寄了东西怎么办 闲鱼退货货收了不退钱怎么办 闲鱼退货卖家收到东西不退钱怎么办 淘宝店铺物流服务给差评怎么办 在合肥东方融资网被骗了怎么办 微信今年绑定频繁明年再试怎么办 手机号码注销了微信密码忘了怎么办 摄像师把婚礼资料弄丢了怎么办 青岛拍的婚纱照修的不好怎么办 鞋店剩的鞋都是小码的怎么办 淘宝想买的衣服下架了怎么办 买家要求到付仲裁发生运费怎么办 淘宝退货退款页面刷新不出来怎么办 淘宝退货退款快递单号写错了怎么办 淘宝上已经退款的店家还发货怎么办 千牛买家下单付款了卖家怎么办 京东货到付款支付宝支付退款怎么办 美萍餐饮管理系统下单错误怎么办 淘宝店上传宝贝显示空间不足怎么办 淘宝店品牌被投诉未授权怎么办 淘宝天猫退货单号填错了怎么办