• 【NOIP2014】联合权值


    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1351


    还是挺简单的,一看n个点,n-1条边,就知道是树,所以建一下树。联合权值要求两个点之间距离为2,而每条边的长度均为1,所以共有两种情况,其中一个点是另一个点的父亲的父亲;两个点父亲相同。

    所以我们可以求出每个结点儿子的权值之和,及其权值最大值和次大值,之所以要求次大值,就是为了处理最大值就是本身的情况。

    一开始用的DFS,爆栈了,只有50分,换成BFS,才有70分,而且提示的错误很乱,后来发现edge数组开小了,改完居然就A掉了。。。

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    inline int get_num() {
        int num = 0;
        char c = getchar();
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9')
            num = num * 10 + c - '0', c = getchar();
        return num;
    }
    
    const int maxn = 2e5 + 5;
    
    int head[maxn], eid;
    
    struct Edge {
        int v, next;
    } edge[2 * maxn];
    
    inline void insert(int u, int v) {
        edge[++eid].v = v;
        edge[eid].next = head[u];
        head[u] = eid;
    }
    
    int w[maxn], sum[maxn], maxw[maxn][2], fa[maxn], as, am;
    
    queue<int> q;
    
    inline void bfs() {
        q.push(1);
        fa[1] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int p = head[u]; p; p = edge[p].next) {
                int v = edge[p].v;
                if (sum[v]) continue;
                fa[v] = u;
                q.push(v);
                sum[u] = (sum[u] + w[v]) % 10007;
                if (w[v] > maxw[u][0])
                    maxw[u][1] = maxw[u][0], maxw[u][0] = w[v];
                else if (w[v] > maxw[u][1]) maxw[u][1] = w[v];
            }
        }
    }
    
    inline void bfs2() {
        q.push(1);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int p = head[u]; p; p = edge[p].next) {
                int v = edge[p].v;
                if (fa[u] == v) {
                    as = (as + w[u] * (sum[v] - w[u]) % 10007) % 10007;
                    if (w[u] == maxw[v][0])
                        am = max(am, w[u] * maxw[v][1]);
                    else am = max(am, w[u] * maxw[v][0]);
                } else {
                    as = (as + (2 * (w[u] * sum[v] % 10007) % 10007)) % 10007;
                    am = max(am, w[u] * maxw[v][0]);
                    q.push(v);
                }
            }
        }
    }
    
    int main() {
        int n, u, v;
        n = get_num();
        for (int i = 1; i < n; ++i) {
            u = get_num(), v = get_num();
            insert(u, v);
            insert(v, u);
        }
        for (int i = 1; i <= n; ++i)
            w[i] = get_num();
        bfs();
        bfs2();
        printf("%d %d", am, as);
        return 0;
    }
    AC代码
  • 相关阅读:
    区分.net中的virtual new 与override
    DOM
    两个php函数
    中文字符,全角字符的正则表达式
    CSS实现居中代码大全
    xp纯净版
    A Visit to Two National Parks: Mount Rainier and Valley Forge
    8、检测浏览器和操作系统
    客户
    American History: The Reagan Years
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9836663.html
Copyright © 2020-2023  润新知