zoukankan      html  css  js  c++  java
  • UVALive 5061 Lightning Energy Report --LCA

    题意:给一棵树,每次给u到v的路径上所有点加上一个值,最后输出每个点的权值(初始为0)

    解法:每次在u,v间加k时,只要让u,v点的权值加上k,u,v的LCA处减去k(因为LCA的子树中加了两个k),再在LCA的父亲(如果有的话)减k,免除对上面的影响。最后dfs一遍,ans[u] += ans[v] (v是u的所有儿子)即可。

    这里LCA用RMQ求的。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    using namespace std;
    #define N 100107
    
    int fa[N],ans[N];
    vector<int> G[N];
    int ati[N],f[N],bn,b[N],dp[N][32],ind;
    
    void dfs(int u,int fa) {
        for(int i=0;i<G[u].size();i++) {
            int v = G[u][i];
            if(v == fa) continue;
            dfs(v,u);
            ans[u] += ans[v];
        }
    }
    
    void init()
    {
        memset(ati,0,sizeof(ati));
        memset(f,0,sizeof(f));
        memset(b,0,sizeof(b));
        memset(dp,0,sizeof(dp));
        bn = ind = 0;
    }
    
    void dfs_2(int u,int father)
    {
        int tmp = ++ind;
        f[tmp] = u;
        b[++bn] = tmp;
        ati[u] = bn;
        for(int i=0;i<G[u].size();i++)
        {
            int v = G[u][i];
            if(v == father) continue;
            fa[v] = u;
            dfs_2(v,u);
            b[++bn]=tmp;
        }
    }
    
    void RMQ_init(int n)
    {
        for (int i=1; i<=n; i++)  dp[i][0]=b[i];
        int m=floor(log((double)n*1.0)/log((double)2.0));
        for (int j=1; j<=m; j++)
          for (int i=1; i<=n-(1<<j)+1; i++)
              dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    
    int RMQ(int l,int r)
    {
        int k=floor(log((double)r-l+1)/log(2.0));
        return min(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    
    int LCA(int a,int b)
    {
        if (ati[a] > ati[b]) swap(a,b);
        return f[RMQ(ati[a],ati[b])];
    }
    
    int main()
    {
        int t,cs = 1,i,n,m,u,v,k;
        scanf("%d",&t);
        while(t--)
        {
            init();
            memset(G,0,sizeof(G));
            memset(ans,0,sizeof(ans));
            scanf("%d",&n);
            for(i=0;i<n-1;i++) {
                scanf("%d%d",&u,&v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            dfs_2(0,-1);
            RMQ_init(bn);
            scanf("%d",&m);
            while(m--) {
                scanf("%d%d%d",&u,&v,&k);
                int lca = LCA(u,v);
                ans[u] += k, ans[v] += k;
                ans[lca] -= k;
                if(lca != 0) ans[fa[lca]] -= k;
            }
            dfs(0,-1);
            printf("Case #%d:
    ",cs++);
            for(i=0;i<n;i++) printf("%d
    ",ans[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    async await promise写法
    nginx自动启动脚本
    nginx源码编译安装
    PHP源码编译安装
    MySQL修改root密码的多种方法
    PKG_CONFIG_PATH变量 与 ld.so.conf 文件
    confluence5.65+CentOS+mysql安装破解
    nigos core 安装配置
    cacti+CentOS6.5
    Linux+mysql+apache+php
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4231392.html
Copyright © 2011-2022 走看看