Submission #1146898

#TimeUsernameProblemLanguageResultExecution timeMemory
1146898darkkyMuseum (CEOI17_museum)C++20
20 / 100
775 ms1114112 KiB
// https://oj.uz/problem/view/CEOI17_museum

#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int n, k, x; cin >> n >> k >> x;

    vector<vector<pair<int, int>>> adj(n + 1);

    for (int i=1, u, v, w; i<n; i++) {
        cin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    // dp[i][j][0] : the minimum cost to visit j nodes starting from node i
    // dp[i][j][1] : the minimum cost to visit j nodes starting from node i and travel back to i
    vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(n + 1, vector<int>(2, 0)));
    vector<int> sz(n + 1, 0);

    for (int i=1; i<=n; i++) {
        for (int j=2; j<=n; j++) {
            dp[i][j][0] = dp[i][j][1] = INF;
        }
    }

    function<int(int, int)> findSize = [&] (int u, int p) -> int {
        sz[u] = 1;
        for (auto &[v, _] : adj[u]) {
            if (v == p) continue;
            sz[u] += findSize(v, u);
        }

        return sz[u];
    };

    findSize(x, 0);

    function<void(int, int)> dfs = [&] (int u, int p) -> void {
        int total = 1; // the total number of nodes can visit from node u
        for (auto &[v, w] : adj[u]) {
            if (v == p) continue;
            dfs(v, u);
            total += sz[v];
            for (int i = total; i >= 2; i--) {
                for (int j=0; j<=min(i, sz[v]); j++) {
                // for (int j = max(0, i - total + sz[v]); j <= min(i, sz[v]); j++) { // take j nodes from v
                    // go v first, going back to -> go others, not going back to u
                    dp[u][i][0] = min(dp[u][i][0], dp[u][i-j][0] + dp[v][j][1] + 2 * w);

                    // go other first, go back to u -> go v, not not going back to u
                    dp[u][i][0] = min(dp[u][i][0], dp[u][i-j][1] + dp[v][j][0] + w);

                    // go other first, going back to u -> go v, going back to v
                    dp[u][i][1] = min(dp[u][i][1], dp[u][i-j][1] + dp[v][j][1] + 2 * w); 
                }
            }
        }
    };


    dfs(x, 0);

    cout << dp[x][k][0] << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...