• NOIP2014 联合权值


    题目链接

    https://www.luogu.org/problemnew/show/P1351

    这道题40分钟AC掉了,不算快

    但是我WA了三次……

    考试的时候只能交一次……

    首先我看到样例就给误导了,以为距离为2的路径只有儿子到爷爷这一段

    然后分分钟敲好,加上去WA

    然后仔细想了想,貌似还有一种情况,就是一个父亲的两个儿子

    写完后交,又WA

    发现有的地方没有取模,爆int……

    最后该取模的地方还没有发现完全,交上去WA

    最后想到统计权值和的时候要取模

    终于AC……

    以前一般认为相乘的式子要取模

    以后注意下一下多个数求和也要注意……

    还有就是要想周全

    不过之后对比一下自己和别人的代码还是学到很多的

    总结

    (1)爷爷的求法可以放到dfs里面作为一个参数,下一层是dfs(v, u, fa)
    (2)对于求和的部分卡了一下。对于每个点,权值有(sum-w[u])*w[u]

    可以写个for算一遍

    不过这个for可以省去

    拆开后就是sum * w[u] - w[u] * w[u]

     所有的u加起来就是

    sum * (w[u1] + w[u2]……) - w[u1] - w[u2]……

    sum * sum- w[u1] - w[u2]……

    所以记录一下w[u1] * w[u1] + w[u2] * w[u2]……就好了

    (3)注意看每一个地方会不会爆int,要取模

    (4)思维要周全

    (5)维护最大值和次大值的写法要写对

    #include<bits/stdc++.h>
    #define REP(i, a, b) for(register int i = (a); i < (b); i++)
    #define _for(i, a, b) for(register int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXN = 2e5 + 10;
    const int MOD = 10007;
    
    struct Edge{ int to, next; };
    Edge e[MAXN << 1];
    int head[MAXN], tot;
    int w[MAXN], n, m, ans, maxt; 
    
    void AddEdge(int from, int to)
    {
        e[tot] = Edge{to, head[from]};
        head[from] = tot++;
    }
    
    void read(int& x)
    {
        int f = 1; x = 0; char ch = getchar();
        while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
        while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
        x *= f;
    }
    
    void dfs(int u, int fa, int g)
    {
        int max1 = 0, max2 = 0, sum = 0, t = 0;
        for(int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            if(v == fa) continue;
            dfs(v, u, fa);
            
            t = (t + w[v] * w[v]) % MOD;
            sum = (sum + w[v]) % MOD;
            if(w[v] > max1) { max2 = max1, max1 = w[v]; }
            else if(w[v] > max2) max2 = w[v];
        }
        
        maxt = max(maxt, max(w[u] * w[g], max1 * max2));
        ans = (ans + w[u] * w[g] * 2 % MOD + (sum * sum % MOD - t + MOD)) % MOD;
    }
    
    int main()
    {
        memset(head, -1, sizeof(head)); tot = 0;
        scanf("%d", &n);
        REP(i, 1, n)
        {
            int u, v; read(u); read(v);
            AddEdge(u, v); AddEdge(v, u);
        }
        _for(i, 1, n) read(w[i]);
        
        dfs(1, 0, 0);
        printf("%d %d
    ", maxt, ans);
        
        return 0;
    }
  • 相关阅读:
    Spring IOC容器基于配置文件装配Bean(5) ------通过工厂方法配置bean
    Spring IOC容器基于配置文件装配Bean(4) ------bean生命周期
    Spring IOC容器基于配置文件装配Bean(3) ------装配集合属性
    Spring IOC容器基于配置文件装配Bean(2) ------通过setter或构造方法注入
    Spring IOC容器基于配置文件装配Bean(1) ------设置autowire自动装配
    Java实现序列化的作用和目的
    静态语言与动态语言
    C# WinForm 界面控件
    C# 中类与继承等概念
    C# 中的函数与方法
  • 原文地址:https://www.cnblogs.com/sugewud/p/9876195.html
Copyright © 2020-2023  润新知