Submission #1370719

#TimeUsernameProblemLanguageResultExecution timeMemory
1370719leolin0214Closing Time (IOI23_closing)C++20
35 / 100
1096 ms35420 KiB
#include "closing.h"

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <tuple>
#include <queue>

#define ff first
#define ss second

using namespace std;

struct Tree {
    int n;
    vector<vector<pair<int, long long>>> adj;
    Tree(int _n) : n(_n), adj(n) {}
    void add_edge(int u, int v, long long w) {
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    vector<long long> distance(int root) {
        vector<long long> dis(n);
        auto dfs = [&] (auto dfs, int u, int p) -> void {
            for (auto [v, w]: adj[u]) {
                if (v == p) continue;
                dis[v] = dis[u] + w;
                dfs(dfs, v, u);
            }
        };
        dfs(dfs, root, -1);
        return dis;
    }

    int easy_solve(int x, int y, long long k) {

        using pii = pair<long long, int>;
        priority_queue<pii, vector<pii>, greater<pii>> pq;
        pq.push({0, x});
        pq.push({0, y});

        long long cost = 0;
        int ans = 0;

        vector<bool> vis(n);
        while (pq.size()) {
            auto [d, u] = pq.top(); pq.pop();
            if ((cost += d) <= k) ans++;
            else break;
            vis[u] = true;
            for (auto [v, w]: adj[u]) {
                if (vis[v]) continue;
                pq.push({d + w, v});
            }
        }

        return ans;
    }

    int solve(int x, int y, long long k) {

        int ans = easy_solve(x, y, k);

        vector<vector<long long>> dis(2);
        dis[0] = distance(x);
        dis[1] = distance(y);

        vector<long long> both(n), single(n);
        for (int i=0; i<n; i++) both[i] = max(dis[0][i], dis[1][i]);
        for (int i=0; i<n; i++) single[i] = min(dis[0][i], dis[1][i]);

        vector<int> o(n);
        iota(o.begin(), o.end(), 0);
        sort(o.begin(), o.end(), [&] (int i, int j) {return both[i] < both[j];});

        vector<bool> bo(n), uni(n);
        vector<int> path;
        auto dfs = [&] (auto dfs, int u, int p) -> bool {
            path.push_back(u);
            if (u == y) return true;
            for (auto [v, w]: adj[u]) {
                if (v == p) continue;
                if (dfs(dfs, v, u)) return true;
            }
            path.pop_back();
            return false;
        };  
        dfs(dfs, x, -1);
        for (int u: path) uni[u] = 1;

        
        // long long ocost = 0;
        for (int u: o) {
            bo[u] = true;
            uni[u] = false;
            // ocost += both[u];

            long long cost = 0;
            vector<bool> vis(n);

            using pii = tuple<int, long long, int>;
            priority_queue<pii, vector<pii>, greater<pii>> pq;
            for (int i=0; i<n; i++) {
                if (bo[i]) {
                    pq.push({-1, both[i], i});
                }
            }

            int res = 0;
            while (pq.size()) {
                auto [ty, s, u] = pq.top(); pq.pop();

                if (vis[u]) continue;
                if (cost + s > k) break;

                vis[u] = true;
                cost += s;
                if (bo[u]) {
                    res += 2;
                }else{
                    res += 1;
                }

                for (auto [v, w]: adj[u]) {
                    if (vis[v]) continue;
                    if (bo[v]) continue;
                    pq.push({uni[v] ? 0 : +1, single[v], v});
                }
            }


            if (vis[x] && vis[y]) {
                ans = max(ans, res);
            }
        }


        return ans;
    }
};

int max_score(int N, int X, int Y, long long K,
              std::vector<int> U, std::vector<int> V, std::vector<int> W)
{
    Tree t(N);
    for (int i=0; i<N-1; i++) t.add_edge(U[i], V[i], W[i]);
    return t.solve(X, Y, K);
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...