zoukankan      html  css  js  c++  java
  • Luogu P2052 [NOI2011]道路修建

    吐槽一下

    我开了(-O2)优化结果跑的更慢了什么鬼???!!!

    我怕不是吸了一口毒氧气

    不要脸的放上我的博客,欢迎大家前来面基

    题目大意

    给定一棵有(n)个节点的树,树中有({n-1})条边,每条边花费的价格是这条边两侧的点的数量的差的绝对值和这条边长度的积。求这棵树的总花费。

    解题思路

    以节点(1)作为这棵树的根节点,其实选哪个都可以从题中可以得出一个基本的结论,一条边的两边的点的数量分别等于终点节点儿子的数量(+1)和起点节点祖先的数量。我们可以通过遍历整棵树将每个节点儿子的数量预处理出来。

    在预处理的同时可以进行统计。到最后输出Ans就可以

    附上代码

    当然不能少了代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define int long long
    
    using namespace std;
    
    const int maxn = 1e6+3;
    int n, fir[maxn], nx[maxn<<1], u[maxn<<1], v[maxn<<1], w[maxn<<1], s[maxn], Ans;
    bool vis[maxn];
    inline int DFS(int x, int fr) {
        if(s[x] != 1) return s[x];
        int k = fir[x];
        while (k != -1) {
            if(fr != v[k]) {
                s[x] += DFS(v[k], x);
                Ans += abs(n-2*s[v[k]]) * w[k];
            }
            k = nx[k];
        }
        return s[x];
    }
    
    main() {
        scanf("%lld", &n);
        memset(fir, -1, sizeof(fir));
        fill(s+1, s+1+n, 1);
        for(int i=1; i<=(n-1)*2; i++) {
            scanf("%lld%lld%lld", &u[i], &v[i], &w[i]);
            nx[i] = fir[u[i]];
            fir[u[i]] = i;
            u[i+1] = v[i], v[i+1] = u[i], w[i+1] = w[i];
            i++;
            nx[i] = fir[u[i]];
            fir[u[i]] = i;
        }
        vis[1] = 1;
        DFS(1, 1);
        printf("%lld", Ans);
    }
    
  • 相关阅读:
    微信OpenID获取
    2015总结及2016目标
    python start
    csv到mysql数据库如何分割
    读书 --- 老码识途
    读书--编写高质量代码 改善C#程序的157个建议2
    读书--编写高质量代码 改善C#程序的157个建议
    BinarySearch
    在aspx中写c#
    AWS 2020 Innovate所有视频
  • 原文地址:https://www.cnblogs.com/bljfy/p/9428190.html
Copyright © 2011-2022 走看看