• HDU


    这道题相当于将这两题结合:

      http://poj.org/problem?id=2763

      http://codeforces.com/gym/101808/problem/K

    题意:有N各点N条边的带权无向图(相当于一棵树多了一条边),两种操作:修改一条边的权值;求两点间的最短路径。

    分析:将任意一条边取出来,其余n-1条边可以结合LCA解最短路。询问时,比较通过取出的边和仅通过树上的边的路径的大小,最小值就是两点的最短路径。

    树状数组差分维护点到根节点的距离,根据dfs序来记录需要维护的范围。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define maxn 100005
    typedef long long LL;
    struct Edge{
        int to,next,id;
    }edge[maxn<<1];
     
    int n,a[maxn],head[maxn],dep[maxn<<1],cnt,pos[maxn],dfs_seq[maxn<<1],dfn,f[maxn<<1][20];
    int L[maxn],R[maxn],dfs_clock,G[maxn];
    LL W[maxn],C[maxn];
    
    inline void add(int u,int v,int id){
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        edge[cnt].id=id;
        head[u]=cnt++;
    }
     
    inline int lowbit(int x){return (x)&(-x);}
     
    void init(){
        memset(head,-1,sizeof(head));
        memset(pos,-1,sizeof(pos));
        memset(C,0,sizeof(C));
        cnt=dfn=0;
        dfs_clock=0;
    }
     
    void dfs(int u,int deep)
    {
        dfs_seq[dfn]=u,dep[dfn]=deep,pos[u]=dfn++;
        L[u]=++dfs_clock;
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            if(pos[v]==-1){
                G[edge[i].id]=v;                //important
                dfs(v,deep+1);
                dfs_seq[dfn]=u,dep[dfn++]=deep;
            }
        }
        R[u]=dfs_clock;
    }
     
    void init_RMQ(int n)
    {
        for(int i=1;i<=n;++i) f[i][0]=i;
        for(int j=1;(1<<j)<=n;++j)
            for(int i=1;i+(1<<j)-1<=n;++i){
                if(dep[f[i][j-1]]<dep[f[i+(1<<(j-1))][j-1]]) f[i][j]=f[i][j-1];
                else f[i][j]=f[i+(1<<(j-1))][j-1];
            }
    }
     
    inline int RMQ(int L,int R)
    {
        int k=0;
        while(1<<(k+1)<=R-L+1) ++k;
        if(dep[f[L][k]]<dep[f[R-(1<<k)+1][k]]) return f[L][k];
        return f[R-(1<<k)+1][k];
    }
     
    inline int lca(int u,int v)
    {
        if(pos[u]>pos[v]) return dfs_seq[RMQ(pos[v],pos[u])];
        return dfs_seq[RMQ(pos[u],pos[v])];
    }
     
    inline void update(int i,LL x)
    {
        for(;i<=n;i+=lowbit(i)) C[i]+=x;
    }
     
    inline LL sum(int i)
    {
        LL s=0;
        for(;i>0;i-=lowbit(i)) s+=C[i];
        return s;
    }
    
    inline LL dist(int u,int v)
    {
        return sum(L[u])+sum(L[v])-2*sum(L[lca(u,v)]);
    }
     
    int main()
    {
        #ifndef ONLINE_JUDGE
                freopen("in.txt","r",stdin);
                freopen("out.txt","w",stdout);
        #endif
        int i,u,v,k,q,s,T;
        LL w;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&q);
            init();
            for(i=1;i<=n-1;++i){
                scanf("%d%d%lld",&u,&v,&w);
                add(u,v,i);
                add(v,u,i);
                W[i]=w;
            }
            dfs(1,0);
            init_RMQ(dfn-1);
            int X,Y; LL Z;
            scanf("%d%d%lld",&X,&Y,&Z);               //第n条边
            W[n] = Z;
            for(i=1;i<n;++i){
                update(L[G[i]],W[i]);
                update(R[G[i]]+1,-W[i]);
            }
            
            while(q--){
                scanf("%d",&k);
                if(k==0){
                    scanf("%d%lld",&u,&w);
                    if(u==n)
                        W[n] = w;   
                    else{
                        update(L[G[u]],w-W[u]);
                        update(R[G[u]]+1,-w+W[u]);
                        W[u]=w;
                    }
                }
                else{
                    scanf("%d%d",&u,&v);
                    LL ans=dist(u,v);
                    ans=min(ans,dist(u,X)+dist(v,X));
                    ans=min(ans,dist(u,Y)+dist(v,Y));
                    ans=min(ans,dist(u,X)+dist(v,Y)+Z);
                    ans=min(ans,dist(u,Y)+dist(v,X)+Z);
                    printf("%lld
    ",ans);
                }
            }
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    C语言复习---二维数组和二级指针的关系:没关系,别瞎想(重点)
    数据结构(二)栈与队列---回溯法之八皇后问题
    数据结构(二)栈与队列---递归之汉罗塔
    数据结构(二)栈与队列---栈的应用(递归和分治思想)
    数据结构(二)栈与队列---队列
    chmod 权限777 是什么意思(Unix和Linux的各种操作系统下)
    C#:基于WMI查询USB设备
    Eclipse中web项目部署至Tomcat步骤
    CSS设置DIV背景色渐变显示
    通过[蜘蛛协议]Robots.txt禁止搜索引擎收录的方法
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9470162.html
Copyright © 2020-2023  润新知