답안 #840044

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
840044 2023-08-31T02:58:30 Z fanwen Džumbus (COCI19_dzumbus) C++17
110 / 110
39 ms 23856 KB
#include <bits/stdc++.h>

using namespace std;

#define MASK(x) (1LL << (x))
#define BIT(x, i) (((x) >> (i)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define REP(i, n) for (int i = 0, _n = n; i < _n; ++i)
#define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define FORD(i, a, b) for (int i = (a), _b = (b); i >= _b; --i)
#define FORE(i, a, b) for (int i = (a), _b = (b); i < _b; ++i)
#define debug(...) "[" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define file(name) if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }

template <class A, class B> bool minimize(A &a, B b)  { if (a > b) { a = b; return true; } return false; }
template <class A, class B> bool maximize(A &a, B b)  { if (a < b) { a = b; return true; } return false; }

#define int long long

struct disjoint_set {
    vector <int> lab;
    disjoint_set () {}
    disjoint_set (int n) : lab(n + 1, -1) {}
    int find(int u) { return lab[u] < 0 ? u : lab[u] = find(lab[u]); }
    bool merge(int u, int v) {
        u = find(u); v = find(v);
        if(u == v) return false;
        if(lab[u] > lab[v]) swap(u, v);
        lab[u] += lab[v];
        lab[v] = u;
        return true;
    }
    bool same_component (int u, int v) { return find(u) == find(v); }
    int component_size(int i) { return -lab[find(i)]; }
};

const int MAXN = 1e3 + 5;

int N, M, Q, D[MAXN], sz[MAXN], vis[MAXN];
vector <int> adj[MAXN];
long long dp[2][MAXN][MAXN], F[MAXN];

void dfs(int u, int p) {
    vis[u] = true;
    sz[u] = 1;
    dp[0][u][0] = 0;
    for (auto v : adj[u]) if(v != p) {
        dfs(v, u);
        FORD(b, sz[u], 0) FORD(a, sz[v], 0) {
            minimize(dp[0][u][a + b], min(dp[0][v][a], dp[1][v][a]) + dp[0][u][b]);
            minimize(dp[1][u][a + b], min(dp[0][v][a], dp[1][v][a]) + dp[1][u][b]);
            minimize(dp[1][u][a + b + 1], dp[1][v][a] + dp[0][u][b] + D[u]);
            minimize(dp[1][u][a + b + 1], dp[0][v][a] + dp[1][u][b] + D[v]);
            minimize(dp[1][u][a + b + 2], dp[0][v][a] + dp[0][u][b] + D[u] + D[v]);
        }
        sz[u] += sz[v];
    }
}

void you_make_it(void) {
    cin >> N >> M;
    FOR(i, 1, N) cin >> D[i];
    vector <pair <int, int>> edges(M);
    for (auto &[u, v] : edges) cin >> u >> v;
    sort(ALL(edges), [&](const pair <int, int> &a, const pair <int, int> &b) {
         return D[a.first] + D[a.second] < D[b.first] + D[b.second];
    });
    disjoint_set dsu(N);
    for (auto [u, v] : edges) {
        if(dsu.merge(u, v)) {
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
    }
    memset(dp, 0x3f, sizeof dp);
    memset(F, 0x3f, sizeof F);
    F[0] = 0;

    FOR(i, 1, N) if(!vis[i]) {
        dfs(i, 0);
        FORD(j, N, 0) {
            FOR(u, 2, min(sz[i], j)) {
                minimize(F[j], F[j - u] + min(dp[0][i][u], dp[1][i][u]));
            }
        }
    }
    vector <pair <int, int>> _F;
    FOR(i, 2, N) {
        _F.emplace_back(F[i], i);
    }
    sort(ALL(_F));
    cin >> Q;
    vector <pair <int, int>> queries(Q);
    vector <int> ans(Q);
    int Max = 0;
    REP(i, Q) {
        cin >> queries[i].first;
        queries[i].second = i;
    }
    sort(ALL(queries));
    int j = 0;
    for (auto [u, i] : queries) {
        while(j < N - 1 && _F[j].first <= u) maximize(Max, _F[j++].second);
        ans[i] = Max;
    }
    REP(i, Q) cout << ans[i] << '\n';
}

signed main() {

#ifdef LOCAL
    freopen("TASK.inp", "r", stdin);
    freopen("TASK.out", "w", stdout);
#endif
    auto start_time = chrono::steady_clock::now();

    cin.tie(0), cout.tie(0) -> sync_with_stdio(0);

    you_make_it();

    auto end_time = chrono::steady_clock::now();

    cerr << "\nExecution time : " << chrono::duration_cast <chrono::milliseconds> (end_time - start_time).count() << "[ms]" << endl;

    return (0 ^ 0);
}

// Dream it. Wish it. Do it.
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 16340 KB Output is correct
2 Correct 10 ms 16332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 16340 KB Output is correct
2 Correct 10 ms 16332 KB Output is correct
3 Correct 36 ms 23224 KB Output is correct
4 Correct 39 ms 23856 KB Output is correct
5 Correct 38 ms 23540 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 33 ms 21588 KB Output is correct
2 Correct 31 ms 22676 KB Output is correct
3 Correct 34 ms 23212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 16340 KB Output is correct
2 Correct 10 ms 16332 KB Output is correct
3 Correct 36 ms 23224 KB Output is correct
4 Correct 39 ms 23856 KB Output is correct
5 Correct 38 ms 23540 KB Output is correct
6 Correct 33 ms 21588 KB Output is correct
7 Correct 31 ms 22676 KB Output is correct
8 Correct 34 ms 23212 KB Output is correct
9 Correct 33 ms 23012 KB Output is correct
10 Correct 36 ms 23644 KB Output is correct
11 Correct 37 ms 23372 KB Output is correct