zoukankan      html  css  js  c++  java
  • b_lg_时态同步(后序遍历统计每棵子树的最大高度)

    题目大意:有一个激发器,与若干个元件与之相连,它们组成一棵树,叶结点可能不在同一水平线上,你可以花费1代价使得一条导线增加电流的一个单位的传输时间,问至少要使用多少道具才能让叶结点处于统一水平面上。
    输入:n 行 a,b,t。表示该条导线连接节点a与节点b,且激励电流通过这条导线需要t个单位时间。

    方法一:

    比较容易想到的是:先移动靠近根节点的结点(假设为u)会最小化开销(ps:牵一发而动u的子树全身)

    后序遍历从低到高枚举并统计每一刻子树的高度,比如现有根节点 u,有 u 的两个子节点 s1、s2,u到s1的距离为3,u到s2的距离为1,d[u]=max(d[s1], d[2])=3,需要花费的道具数就是:\(\sum_{1}^{size(tree_u)}(d[u]-(d[s_i]+w_{u->s_i})\)的总和,即根节点的最大高度 -(直接子节点的最小高度+根到直接子节点的边权)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+5;
    struct node {
        ll u,w;
    };  
    vector<node> g[N];
    ll ans, d[N], vis[N];
    
    void dfs(int u, int fa) {
        for (auto& to : g[u]) {
            int v=to.u, w=to.w;
            if (v!=fa) {
                dfs(v,u);
                d[u]=max(d[u], d[v]+w);
            }
        }
        for (auto& to : g[u]) {
            int v=to.u, w=to.w;
            if (v!=fa) {
                ans+=d[u]-(d[v]+w);
            }
        }
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int n,s,u,v,w; cin>>n>>s;
        for (int i=1; i<n; i++) {
            cin>>u>>v>>w;
            g[u].push_back({v,w});
            g[v].push_back({u,w});
        }
        dfs(s,-1);
        cout<<ans;
        return 0;
    }
    

    复杂度分析

    • Time\(O(v+e)\)
    • Space\(O(v+e)\)
  • 相关阅读:
    URL提交之前对数据编码
    软件工程概论第三章概括
    软件工程概论第七章概括
    软件工程概论第四章概括
    软件工程概论第五章概括
    软件工程概论第一章概括
    《人月神话》观后感
    软件工程概论第六章概括
    软件工程概论第二章概括
    MySQL语句
  • 原文地址:https://www.cnblogs.com/wdt1/p/13668894.html
Copyright © 2011-2022 走看看