基环树 DP 板子题求调
查看原帖
基环树 DP 板子题求调
804607
rainygame楼主2023/12/28 22:19

不能过 hack qwq。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 100010

int n, u, v, ans, tot;
int in[MAXN], c[MAXN];
int f[MAXN][2], g[MAXN][2];
list<int> e[MAXN];
queue<int, list<int>> que;
bitset<MAXN> loop;
double k;

void toposort(){
    for (int i(1); i<=n; ++i){
        if (in[i] == 1) que.push(i);
    }

    while (!que.empty()){
        u = que.front();
        que.pop();
        for (auto i: e[u]){
            if ((--in[i]) == 1) que.push(i);
        }
    }

    for (int i(1); i<=n; ++i){
        if (in[i] == 2){
            loop.set(i);
            c[++tot] = i;
        }
    }
}

void dfs(int x, int fa){
    for (int i: e[x]){
        if (i != fa && !loop.test(i)){
            dfs(i, x);
            f[x][0] += max(f[i][0], f[i][1]);
            f[x][1] += f[i][0];
        }
    }
}

void dp(bool pos){
    memset(g, -0x3f, sizeof(g));
    g[1][pos] = f[c[1]][pos];
    for (int i(2); i<=tot; ++i){
        g[i][1] = g[i-1][0] + f[c[i]][1];
        g[i][0] = max(g[i-1][0], g[i-1][1]) + f[c[i]][0];
    }
    ans = max(ans, (pos ? g[tot][0] : max(g[tot][0], g[tot][1])));
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n;
    for (int i(1); i<=n; ++i) cin >> f[i][1];
    for (int i(1); i<=n; ++i){
        cin >> u >> v;
        ++u;
        ++v;
        ++in[u];
        ++in[v];
        e[u].push_back(v);
        e[v].push_back(u);
    }
    toposort();
    for (int i(1); i<=tot; ++i) dfs(c[i], 0);
    dp(0);
    dp(1);

    cin >> k;
    cout << fixed << setprecision(1) << ans * k;

    return 0;
}

2023/12/28 22:19
加载中...