请问一下我的dp思路有什么问题吗?
查看原帖
请问一下我的dp思路有什么问题吗?
527629
iqer楼主2022/3/15 11:58

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;
}
2022/3/15 11:58
加载中...