联合权值

联合权值

https://ac.nowcoder.com/acm/problem/16495

题意:
一颗树中的每一个点都有自己的权值,每条线段长度为1,求所有距离为2的点对权值积的和,以及他们权值积的最大值。

思路:要找到长度为2的所有组,可以通过遍历每一个点找到与他连接的点。这些点都可以通过这个点到达对方,距离为2

代码:

代码块
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define ll long long
#ifdef ONLINE_JUDGE
#else
#define scanf scanf_s
#endif // ONLINE_JUDGE
#define FOR(i,a,b) for(int i = a;i <= b;i++)
#define ROF(i,a,b) for(int i = a;i >= b;i--)
ll read() {
    ll X = 0, w = 1; char c = getchar();
    while (c < '0' || c>'9') { if (c == '-') w = -1; c = getchar(); }
    while (c >= '0' && c <= '9') X = X * 10 + c - '0', c = getchar();
    return X * w;
}
ll poww(ll a, ll b, ll mod) {
    ll base = 1;
    while (b) {
        if (b & 1) { base = base * a % mod; }
        b >>= 1; a = a * a % mod;
    }
    return base;
}
const int maxx = 200000 + 50;
const int mod = 10007;
struct edge {
    int to = 0, nxt = 0;
}e[maxx * 2];
int head[maxx];
int ary[maxx];
int ct = 1;
void insert(int a,int b) {
    if (head[a]) e[ct].nxt = head[a];
    e[ct].to = b, head[a] = ct++;
}
int big = 0, sum = 0;
void dfs(int a) {
    int cont = 0; int shuzu[maxx];
    int first = 0, second = 0;
    for (int j = head[a]; j != 0; j = e[j].nxt) {
        int b = e[j].to;
        if (b) { 
            if (ary[b] > first)second = first, first = ary[b];
            else if (ary[b] > second) second = ary[b];
            shuzu[cont++] = ary[b];
        }
    }
    if (cont <= 1) { return; }//说明只有一个数字
    big = max(big, first*second);
    int he = 0; int sqsum = 0;
    for (int i = 0; i < cont; i++){
        he = (he + shuzu[i]) % mod;
        sqsum = (sqsum + shuzu[i] * shuzu[i]) % mod;
    }
    sum = (sum + he * he - sqsum + mod) % mod;
}
int main() {
    int n; n = read();
    int a, b;
    FOR(i, 2, n)a = read(), b = read(), insert(a, b), insert(b, a);
    FOR(i, 1, n) ary[i] = read();
    FOR(i, 1, n) dfs(i);
    cout << big << " " << sum << endl;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务