距离为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 }