• 联合权值——树上问题2014noip


    联合权值

    题面

    思路

    枚举每一个点作为中间节点

    计算出它所有儿子y的权值和sum

    每个儿子的要和其他儿子算一遍联合权值,

    所以是(w[y] * (sum - w[y]))

    最大值的话顺便记录下来就行

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 400000;
    int ne[N], ver[N], idx, head[N];
    long long ans;
    long long sum;
    long long a[N];
    int n;
    long long res;
    const int mod = 10007;
    void add(int u, int v) {
      ne[idx] = head[u];
      ver[idx] = v;
      head[u] = idx;
      idx++;
    }
    
    void dfs(int x) {
      long long t1 = 0, t2 = 0;
      sum = 0;
      for (int i = head[x]; i != -1; i = ne[i]) {
        int j = ver[i];
        sum = ((sum + a[j]) + mod) % mod;
        if (a[j] > t1) {
          t2 = t1;
          t1 = a[j];
        } else if (a[j] > t2) {
          t2 = a[j];
        }
      }
      ans = max(ans, (long long)t2* t1 );
      for (int i = head[x]; i != -1; i = ne[i]) {
        int j = ver[i];
        res = (res + ((long long)(sum - a[j]) * a[j] % mod) + mod) % mod;
      }
    }
    int main() {
      memset(head, -1, sizeof(head));
      scanf("%d", &n);
      for (int i = 1; i < n; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
        add(b, a);
      }
      for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
      for (int i = 1; i <= n; i++) {
        dfs(i);
      }
      cout <<ans << ' ' << (res + mod) % mod << endl;
      return 0;
    }
    

    注意:

    前一个答案不用取模,要看清楚题面

  • 相关阅读:
    应用层
    传输层
    一元函数微分学
    函数、极限、连续
    网络层习题与真题
    网络层
    数据链路层习题与真题
    二、使用kubeadm部署k8s
    一、Kubernetes概述
    二、rsync文件同步
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/14077836.html
Copyright © 2020-2023  润新知