求调 or 请求开大空间限制?
查看原帖
求调 or 请求开大空间限制?
589916
August_Light楼主2023/6/10 15:40

前 55 个点 AC,最后一个点 MLE。

不知道是我的代码有正确性问题还是单纯被卡空间了。

#include <bits/stdc++.h>
#define debug(x) fprintf(stderr, ""#x"\t= %d\n", x); fflush(stderr)
#define bar() fprintf(stderr, "---------\n"); fflush(stderr)
using namespace std;
const int MAXN = 5e5 + 100;
const int INF = 0x7f7f7f7f;

int n;

vector<int> G[MAXN];
void addedge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
}

namespace find_ring {
    int dfs1_fa[MAXN]; // dfs1 时的父亲,为了回溯找环
    bitset<MAXN> vis; // 已被 dfs1 过
    vector<int> ring;
    bitset<MAXN> on_ring;
    void dfs1(int u, int fa) {
        vis[u] = 1; dfs1_fa[u] = fa;
        int fa_cnt = 0;
        for (auto v : G[u]) {
            if (v == fa) {
                if (fa_cnt == 0)
                    fa_cnt++;
                else {
                    on_ring[u] = 1;
                    on_ring[v] = 1;
                    ring.push_back(u);
                    ring.push_back(v);
                }
                continue;
            }
            if (!vis[v])
                dfs1(v, u);
            else if (!on_ring[v]) {
                on_ring[u] = 1;
                ring.push_back(u);
                int c = u; do {
                    c = dfs1_fa[c];
                    on_ring[c] = 1;
                    ring.push_back(c);
                } while (c != v);
            }
        }
    }
}
using find_ring::on_ring;
using find_ring::ring;

namespace P1352 {
    int f[MAXN][2];
    void dfs(int u, int fa) {
        f[u][0] = 0;
        f[u][1] = 1;
        for (auto v : G[u]) {
            if (v == fa || on_ring[v])
                continue;
            dfs(v, u);
            f[u][0] += max(f[v][0], f[v][1]);
            f[u][1] += f[v][0];
        }
    }
}

namespace DP_on_ring {
    int a[MAXN];
    int f[MAXN][2];
    int work() {
        int n = ring.size();
        for (int i = 1; i <= n; i++) {
            int u = ring[i-1];
            a[i] = P1352::f[u][1] - P1352::f[u][0];
        }
        f[1][0] = -INF;
        f[1][1] = a[1];

        for (int i = 2; i <= n; i++) {
            f[i][0] = max(f[i-1][0], f[i-1][1]);
            f[i][1] = f[i-1][0] + a[i];
        }
        int ans = f[n][0];

        memset(f, 0, sizeof(f));

        // 不选 1
        f[1][0] = 0;
        f[1][1] = -INF;
        for (int i = 2; i <= n; i++) {
            f[i][0] = max(f[i-1][0], f[i-1][1]);
            f[i][1] = f[i-1][0] + a[i];
        }
        ans = max(ans, max(f[n][0], f[n][1]));
        for (auto u : ring)
            ans += P1352::f[u][0];
        return ans;
    }
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int u;
        cin >> u;
        addedge(i, u);
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        if (find_ring::vis[i])
            continue;
        ring.clear();
        find_ring::dfs1(i, 0);
        for (auto u : ring)
            P1352::dfs(u, 0);
        res += DP_on_ring::work();
    }
    cout << res << endl;
}
2023/6/10 15:40
加载中...