dp dp[i]表示以节点i为跟节点的子树中所有节点得到的最大联合权值和 然后转移: dp[i] = dpj + 两两子节点间产生的贡献+孙子节点与根节点间产生的贡献 请问哪里有什么问题吗?
#include <bits/stdc++.h>
using namespace std;
#define debugs
typedef long long ll;
const int maxn = 2e5 + 5;
const int mod = 10007;
ll n, v[maxn];
vector<int> q[maxn];
ll dp[maxn];
ll ans = 0;
void dfs(int op, int f){
//cout << "dfs(" << op << "," << f << ")" << endl;
//cout << "start: "<< dp[op] << endl;
ll pre = 0;
for(int i = 0; i < q[op].size(); ++i){
if(q[op][i] == f)continue;
dfs(q[op][i], op);
(dp[op] += dp[q[op][i]]) %= mod;
dp[op] += 2ll * pre * v[q[op][i]];
(pre += v[q[op][i]]) %= mod; // 之前子节点的前缀和
int t = q[op][i];
//cout << t << endl;
for(int j = 0; j < q[t].size(); ++j){
if(q[t][j] == op)continue;
(dp[op] += 2ll * v[op] * v[q[t][j]]) %= mod;
ans = max(ans, 1ll * v[op] * v[q[t][j]]);
}
}
// cout << "end: " << dp[op] << endl;
}
int main(){
cin >> n;
for(int i = 1; i < n; ++i){
int u, v; cin >> u >> v;
q[u].push_back(v);
q[v].push_back(u);
}
for(int i = 1; i <= n; ++i)cin >> v[i], v[i] %= mod;
dfs(1, 0);
cout << ans << " " << dp[1] << endl;
#ifdef debug
for(int i = 1; i <= n; ++i){
cout << i << " : ";
for(int j = 0; j < q[i].size(); ++j){
cout << q[i][j] << " ";
}cout << endl;
}
for(int i = 1; i <= n; ++i)cout << dp[i] << " ";
#endif
return 0;
}