• SPOJ375 Query on a tree


    https://vjudge.net/problem/SPOJ-QTREE

    题意:

    一棵树,每条边有个权值

    两种操作

    一个修改每条边权值

    一个询问两点之间这一条链的最大边权

    点数<=10000

    多组测试数据,case<=20

    Example

    Input:
    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    
    Output:
    1
    3
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=210000;
    const int inf=0x3fffffff;
    int son[N],father[N],sz[N],head[N],num;
    int ti[N],idx,dep[N],top[N];
    struct edge{
        int ed,nxt;
    }e[N*3];
    struct Edge{
        int x,y,v;
    }E[N*2];
    int max(int a,int b){
        if(a>b)return a;
        return b;
    }
    void addedge(int x,int y){
        e[++num].ed=y;e[num].nxt=head[x];head[x]=num;
        e[++num].ed=x;e[num].nxt=head[y];head[y]=num;
    }
    
    void dfs_find(int u,int fa){//处理每棵子树大小和重儿子 
        sz[u]=1;dep[u]=dep[fa]+1;son[u]=0;father[u]=fa;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].ed;
            if(v==fa)continue;
            dfs_find(v,u);
            sz[u]+=sz[v];
            if(sz[son[u]]<sz[v])son[u]=v;
        }
    }
    void dfs_time(int u,int fa){
        ti[u]=idx++;
        top[u]=fa;
        if(son[u]!=0)dfs_time(son[u],top[u]);//处理同重链上点的top 
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].ed;
            if(v==father[u]||v==son[u])continue;//枚举到了同一重链上的点就跳过 
            dfs_time(e[i].ed,e[i].ed);
        }
    }
    
    struct tree{
        int l,r,v;
    }T[N<<2];
    void buildtree(int l,int r,int id){
        T[id].l=l;T[id].r=r;T[id].v=-inf;
        if(l==r)return;
        int mid=(l+r)>>1;
        buildtree(l,mid,id*2);
        buildtree(mid+1,r,id*2+1);
    }
    void update(int id,int cp,int v){
        if(T[id].l==T[id].r){T[id].v=v;return;}
        int mid=(T[id].l+T[id].r)>>1;
        if(mid>=cp)update(id*2,cp,v);
        if(mid<cp)update(id*2+1,cp,v);
        T[id].v=max(T[id*2].v,T[id*2+1].v);
    }
    int query(int l,int r,int id){
        if(T[id].r==r&&T[id].l==l)return T[id].v;
        int mid=(T[id].l+T[id].r)>>1;
        if(mid>=r)return query(l,r,id*2);
        else if(mid<l)return query(l,r,id*2+1);
        else return max(query(l,mid,id*2),query(mid+1,r,id*2+1));
    }
    int lca(int x,int y){
        int ans=-inf;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans=max(ans,query(ti[top[x]],ti[x],1));
            x=father[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        if(x!=y)ans=max(ans,query(ti[x]+1,ti[y],1));
        return ans;
    }
    int main(){
        int n,t,x,y,v,j;
        char str[100];
        scanf("%d",&t);
        while(t--){
            memset(head,0,sizeof(head));
            num=0;scanf("%d",&n);
            for(int i=1;i<n;i++){
                scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].v);
                addedge(E[i].x,E[i].y);
            }
            dep[1]=0;sz[0]=0;idx=1;
            dfs_find(1,1);
            dfs_time(1,1);
            buildtree(2,n,1);
            for(int i=1;i<n;i++){
                if(dep[E[i].x]<dep[E[i].y])swap(E[i].x,E[i].y);
                update(1,ti[E[i].x],E[i].v);
            }
            while(true){
                scanf("%s",str);
                if(str[0]=='D')break;
                else if(str[0]=='Q'){
                    scanf("%d%d",&x,&y);
                    printf("%d
    ",lca(x,y));
                }
                else if(str[0]=='C'){
                    scanf("%d%d",&j,&v);
                    update(1,ti[E[j].x],v);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    intelliJ IDEA最常用的快捷键
    Git使用说明
    mac快速安装程序
    java面试-String、StringBuffer和StringBuilder的区别
    linux静态与动态库创建及使用实例
    linux下动态库编译的依赖问题
    动态库与静态库的区别
    gcc-4.8.3安装,gdb-7.6安装
    设计模式之单件模式
    设计模式之抽象工厂模式
  • 原文地址:https://www.cnblogs.com/thmyl/p/6850528.html
Copyright © 2020-2023  润新知