联合权值
联合权值
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; }