Submission #684538

# Submission time Handle Problem Language Result Execution time Memory
684538 2023-01-21T14:51:02 Z CatalinT Training (IOI07_training) C++17
100 / 100
51 ms 748 KB
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <functional>
#include <queue>
#include <deque>
#include <stack>
#include <cassert>
#include <iomanip>
#include <cmath>
#include <bitset>
 
using namespace std;

using int64 = long long;

struct Edge {
    int x;
    int y;
    int w;
};

const int MAX_N = 1001;

int N, M;

vector<vector<int>> g;
vector<Edge> edges;

vector<int> par;
vector<int> child_idx;

vector<vector<Edge>> has_lca;

int dp_all[MAX_N];
int dp_minus[MAX_N][10];

int depth[MAX_N];

int bst[1<<10];
int dp[1<<10];
int buf[1<<10];

void dfs1(int v, int p) {
    int idx = 0;
    for (auto u : g[v]) if (u != p) {
        depth[u] = depth[v] + 1;
        child_idx[u] = idx++;
        par[u] = v;
        dfs1(u, v);
    }
}


void dfs2(int v, int p) {
    int idx = 0;
    int nchild = 0;
    vector<int> child;
    for (auto u : g[v]) if (u != p) {
        nchild++;
        child.push_back(u);
        dfs2(u, v);
    }

    memset(bst, 0, sizeof(bst));
    memset(buf, 0, sizeof(buf));

    auto best_cost = [&] (int x, int w, int & msk, int & cur) {
        int last = -1;

        cur += dp_all[x];

        while (x != v) {
            last = child_idx[x];
            
            if (par[x] != v) {
                cur += dp_minus[par[x]][last];
            }

            x = par[x];
        }

        msk |= (1<<last);
    };

    vector<int> cand;

    for (auto e : has_lca[v]) {
        int msk = 0;
        int cur = e.w;
        if (e.x != v) {
            best_cost(e.x, e.w, msk, cur);
        }
        if (e.y != v) {
            best_cost(e.y, e.w, msk, cur);
        }

        if (!bst[msk] && cur) {
            cand.push_back(msk);
        }

        assert(msk);

        bst[msk] = max(bst[msk], cur);

        // cerr << (e.x+1) << " / " << (e.y+1) << " -> " << cur << "\n";
    }

    for (auto c : cand) {
        for (int i = 0; i < nchild; i++) {
            if (c >> i & 1) {
                buf[c] += dp_all[child[i]];
            }
        }
    }

    for (int r = 0; r < nchild + 1; r++) {
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < nchild; i++) {
            if (i == r) continue;
            dp[0] += dp_all[child[i]];
        }

        if (r < nchild)
            dp_minus[v][r] = dp[0];

        dp_all[v] = max(dp_all[v], dp[0]);

        for (int msk = 0; msk < (1<<nchild); msk++) {
            for (auto c : cand) {
                if ((msk & c) == c && !(c & (1<<r))) {
                    // cerr << "=> " << bst[c] << " " << buf[c] << "\n";
                    dp[msk] = max(dp[msk], dp[msk ^ c] + bst[c] - buf[c]);
                    if (r < nchild)
                        dp_minus[v][r] = max(dp_minus[v][r], dp[msk]);
                    dp_all[v] = max(dp_all[v], dp[msk]);
                }
            }
        }
    }

    cerr << v+1 << " " << dp_all[v] << "\n";
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> M;

    g.resize(N);
    has_lca.resize(N);
    child_idx.assign(N, -1);

    int tot = 0;

    for (int i = 0; i < M; i++) {
        int x, y, w;
        cin >> x >> y >> w;

        x--;
        y--;
        tot += w;

        if (!w) {
            g[x].push_back(y);
            g[y].push_back(x);
        } else {
            edges.push_back(Edge{x, y, w});
        }
    }
    
    par.assign(N, -1);
    memset(depth, 0, sizeof(depth));
    dfs1(0, 0);

    for (auto e : edges) {
        int x = e.x;
        int y = e.y;

        // cerr << depth[x] << " " << depth[y] << "\n";

        if ((depth[x] & 1) != (depth[y] & 1))
            continue;

        while (depth[x] > depth[y]) {
            x = par[x];
        }

        while (depth[y] > depth[x]) {
            y = par[y];
        }

        while (x != y) {
            x = par[x];
            y = par[y];
        }

        has_lca[x].push_back(e);
        
        cerr << (e.x+1) << ", " << (e.y+1) << " -> " << (x+1) << "\n";
    }

    dfs2(0, 0);

    cout << tot - dp_all[0] << "\n";

    return 0;
}

Compilation message

training.cpp: In function 'void dfs2(int, int)':
training.cpp:64:9: warning: unused variable 'idx' [-Wunused-variable]
   64 |     int idx = 0;
      |         ^~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 328 KB Output is correct
2 Correct 2 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 15 ms 592 KB Output is correct
2 Correct 16 ms 712 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 328 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 328 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 340 KB Output is correct
2 Correct 2 ms 320 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 332 KB Output is correct
2 Correct 7 ms 340 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 496 KB Output is correct
2 Correct 19 ms 520 KB Output is correct
3 Correct 17 ms 476 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 43 ms 584 KB Output is correct
2 Correct 42 ms 620 KB Output is correct
3 Correct 39 ms 712 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 18 ms 468 KB Output is correct
2 Correct 17 ms 484 KB Output is correct
3 Correct 40 ms 728 KB Output is correct
4 Correct 17 ms 468 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 42 ms 716 KB Output is correct
2 Correct 51 ms 748 KB Output is correct
3 Correct 40 ms 728 KB Output is correct
4 Correct 40 ms 684 KB Output is correct