[luoguP1351] 联合权值(Dfs)

传送门

距离为2的点会产生权值,第一问,只需要在dfs的时候把一个点相邻的点都处理出来就行。

具体处理方式看代码,然而这样只处理了一遍,最后在乘2就好了。

第二问只需要处理一个点相邻的点中最大的和次大的就行。

——代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define LL long long
 5 
 6 const int MAXN = 200001, p = 10007;
 7 int n, cnt;
 8 int head[MAXN], to[MAXN << 1], next[MAXN << 1];
 9 LL max, tot, a[MAXN], sum[MAXN], ans[MAXN], max1[MAXN], max2[MAXN];
10 bool vis[MAXN];
11 
12 inline int read()
13 {
14     int x = 0, f = 1;
15     char ch = getchar();
16     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
17     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
18     return x * f;
19 }
20 
21 inline LL Max(LL x, LL y)
22 {
23     return x > y ? x : y;
24 }
25 
26 inline void add(int x, int y)
27 {
28     to[cnt] = y;
29     next[cnt] = head[x];
30     head[x] = cnt++;
31 }
32 
33 inline void dfs(int u)
34 {
35     int i, v;
36     vis[u] = 1;
37     for(i = head[u]; i ^ -1; i = next[i])
38     {
39         v = to[i];
40         ans[u] = (ans[u] + sum[u] * a[v]) % p;
41         sum[u] = (sum[u] + a[v]) % p;
42         if(a[v] > max1[u]) max2[u] = max1[u], max1[u] = a[v];
43         else if(a[v] > max2[u]) max2[u] = a[v];
44         if(!vis[v]) dfs(v);
45     }
46 }
47 
48 int main()
49 {
50     int i, x, y;
51     n = read();
52     memset(head, -1, sizeof(head));
53     for(i = 1; i < n; i++)
54     {
55         x = read();
56         y = read();
57         add(x, y);
58         add(y, x);
59     }
60     for(i = 1; i <= n; i++) a[i] = read();
61     dfs(1);
62     for(i = 1; i <= n; i++)
63     {
64         tot = (tot + ans[i]) % p;
65         max = Max(max, max1[i] * max2[i]);
66     }
67     printf("%lld %lld
", max, (tot << 1) % p);
68     return 0;
69 }
View Code
原文地址:https://www.cnblogs.com/zhenghaotian/p/6888316.html