답안 #503059

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
503059 2022-01-07T04:42:28 Z tabr Training (IOI07_training) C++17
82 / 100
300 ms 56416 KB
#include <bits/stdc++.h>
using namespace std;
#ifdef tabr
#include "library/debug.cpp"
#else
#define debug(...)
#endif

struct dsu {
    vector<int> p;
    vector<int> sz;
    int n;

    dsu(int _n) : n(_n) {
        p.resize(n);
        iota(p.begin(), p.end(), 0);
        sz.assign(n, 1);
    }

    inline int get(int x) {
        if (p[x] == x) {
            return x;
        } else {
            return p[x] = get(p[x]);
        }
    }

    inline bool unite(int x, int y) {
        x = get(x);
        y = get(y);
        if (x == y) {
            return false;
        }
        if (sz[x] > sz[y]) {
            swap(x, y);
        }
        p[x] = y;
        sz[y] += sz[x];
        return true;
    }

    inline bool same(int x, int y) {
        return (get(x) == get(y));
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    dsu uf(2 * n);
    vector<vector<int>> g(n);
    vector<tuple<int, int, int>> edges;
    for (int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--, b--;
        if (c == 0) {
            g[a].emplace_back(b);
            g[b].emplace_back(a);
            uf.unite(a, b + n);
            uf.unite(a + n, b);
        } else {
            edges.emplace_back(a, b, c);
        }
    }
    vector<tuple<int, int, int>> new_edges;
    int ans = 0;
    for (auto [a, b, c] : edges) {
        ans += c;
        if (uf.same(a, b)) {
            new_edges.emplace_back(a, b, c);
        }
    }
    swap(edges, new_edges);
    m = (int) edges.size();
    vector<vector<int>> d(n);
    for (int i = 0; i < m; i++) {
        auto [a, b, c] = edges[i];
        d[a].emplace_back(i);
        d[b].emplace_back(i);
    }
    vector<map<int, int>> dp(n);
    function<void(int, int)> dfs = [&](int v, int p) {
        vector<int> ch;
        map<int, vector<int>> mp;
        for (int to : g[v]) {
            if (to == p) {
                continue;
            }
            dfs(to, v);
            for (auto [id, cost] : dp[to]) {
                if (id != -1) {
                    mp[id].emplace_back((int) ch.size());
                }
            }
            ch.emplace_back(to);
        }
        int sz = (int) ch.size();
        vector<int> f(1 << sz);
        for (int i = 0; i < sz; i++) {
            f[1 << i] = dp[ch[i]][-1];
        }
        for (auto [id, u] : mp) {
            if (u.size() == 2) {
                int mask = (1 << u[0]) + (1 << u[1]);
                f[mask] = max(f[mask], dp[ch[u[0]]][id] + dp[ch[u[1]]][id] + get<2>(edges[id]));
            }
        }
        for (int id : d[v]) {
            auto u = mp[id];
            if (u.size() == 1) {
                f[1 << u[0]] = max(f[1 << u[0]], dp[ch[u[0]]][id] + get<2>(edges[id]));
                mp[id].emplace_back(-1);
            }
        }
        for (int mask = 0; mask < (1 << sz); mask++) {
            for (int i = 0; i < sz; i++) {
                if (mask & (1 << i)) {
                    f[mask] = max(f[mask], f[(1 << i)] + f[mask ^ (1 << i)]);
                    for (int j = i + 1; j < sz; j++) {
                        if (mask & (1 << j)) {
                            f[mask] = max(f[mask], f[(1 << i) + (1 << j)] + f[mask ^ ((1 << i) + (1 << j))]);
                        }
                    }
                }
            }
        }
        dp[v][-1] = f.back();
        for (int id : d[v]) {
            auto u = mp[id];
            if (u.size() == 0) {
                dp[v][id] = f.back();
            }
        }
        for (auto [id, u] : mp) {
            if (u.size() == 1) {
                int mask = (1 << sz) - 1;
                mask -= 1 << u[0];
                dp[v][id] = f[mask] + dp[ch[u[0]]][id];
            }
        }
    };
    dfs(0, -1);
    ans -= dp[0][-1];
    cout << ans << '\n';
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 460 KB Output is correct
2 Correct 2 ms 460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 118 ms 16392 KB Output is correct
2 Correct 133 ms 18248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 312 KB Output is correct
2 Correct 0 ms 316 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 356 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 460 KB Output is correct
2 Correct 3 ms 716 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 1252 KB Output is correct
2 Correct 9 ms 1348 KB Output is correct
3 Correct 24 ms 3576 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 3652 KB Output is correct
2 Correct 16 ms 1996 KB Output is correct
3 Correct 16 ms 2432 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 1064 KB Output is correct
2 Correct 41 ms 5408 KB Output is correct
3 Execution timed out 434 ms 56416 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 158 ms 19636 KB Output is correct
2 Execution timed out 445 ms 56100 KB Time limit exceeded
3 Halted 0 ms 0 KB -