QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#543782#5102. Dungeon CrawlerHKOI0Compile Error//C++175.8kb2024-09-01 20:14:042024-09-01 20:14:05

Judging History

你现在查看的是最新测评结果

  • [2024-09-01 20:14:05]
  • 评测
  • [2024-09-01 20:14:04]
  • 提交

answer

#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include <bits/stdc++.h>
#define sz(v) (int)v.size()
#define all(v) v.begin(), v.end()

using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (auto x : v) os << x << ' ';
    os << '\n';
    return os;
}

void solve() {
    int n,q; cin >> n >> q;

    ll distAll = 0;
    vector<vector<pair<int, int>>> g(n);
    for (int i = 0; i < n - 1; i++) {
        int u,v,w; cin >> u >> v >> w; u--; v--;
        g[u].emplace_back(v, w);
        g[v].emplace_back(u, w);
        distAll += w;
    }

    distAll *= 2;

    vector<vector<int>> moveTo(n, vector<int>(n, -1));
    vector<vector<int>> moveFrom(n, vector<int>(n, -1));
    for (int root = 0; root < n; root++) {
        function<void(int, int)> dfs = [&](int u, int p) {
            moveTo[u][root] = p;
            moveFrom[root][u] = p;
            for (auto& [v, w] : g[u]) {
                if (v == p) continue;
                dfs(v, u);
            }
        };
        dfs(root, root);
    }

    vector<vector<ll>> distOf(n, vector<ll>(n, 0));
    for (int root = 0; root < n; root++) {
        distOf[root][root] = 0;
        function<void(int, int)> dfs = [&](int u, int p) {
            for (auto& [v, w] : g[u]) {
                if (v == p) continue;
                distOf[root][v] = distOf[root][u] + w;
                dfs(v, u);
            }
        };
        dfs(root, root);
    }

    // arr[u][v] = root is u, forbids subtree of v
    vector<vector<pair<ll, int>>> furthestDistForbid(n, vector<pair<ll, int>>(n)); 
    for (int root = 0; root < n; root++) {
        vector<ll> dp(n, 0);
        vector<int> opt(n, 0);
        for (int u = 0; u < n; u++)
            opt[u] = u;

        function<void(int, int)> dfs = [&](int u, int p) {
            for (auto& [v, w] : g[u]) {
                if (v == p) continue;
                dfs(v, u);
                if (dp[u] < dp[v] + w) {
                    dp[u] = dp[v] + w;
                    opt[u] = opt[v];
                }
            }
        };
        dfs(root, root);

        // if (root == 0) {
        //     for (int u = 0; u < n; u++)
        //         cout << dp[u] << " \n"[u + 1 == n];
        //     for (int u = 0; u < n; u++)
        //         cout << opt[u] + 1 << " \n"[u + 1 == n];
        // }

        ll firstMax = 0, secondMax = 0;
        int firstOpt = root, secondOpt = root;
        for (auto& [v, w] : g[root]) {
            if (dp[v] + w > firstMax) {
                secondMax = firstMax;
                secondOpt = firstOpt;
                firstMax = dp[v] + w;
                firstOpt = opt[v];
            }
            else if (dp[v] + w > secondMax) {
                secondMax = dp[v] + w;
                secondOpt = opt[v];
            }
        }

        // cout << root << ' ' << firstMax << ' ' << firstOpt << ' ' << secondMax << ' ' << secondOpt << '\n';

        for (auto& [v, w] : g[root]) {
            if (opt[v] == firstOpt)
                furthestDistForbid[root][v] = make_pair(secondMax, secondOpt);
            else
                furthestDistForbid[root][v] = make_pair(firstMax, firstOpt);
        }
    }

    auto getLCA = [&](int root, int u, int v) {
        int cur = root;
        while (moveFrom[u][cur] == moveFrom[v][cur])
            cur = moveFrom[u][cur];
        return cur;
    };

    while (q--) {
        int start, key, trap; cin >> start >> key >> trap; start--; key--; trap--;

        const int KEY_TRAP_LCA = getLCA(start, key, trap);
        if (KEY_TRAP_LCA == trap) {
            cout << "impossible\n";
            continue;
        }

        const int KEY_TRAP_LCA_TO_KEY = moveTo[KEY_TRAP_LCA][key];

        ll ans = LLONG_MAX;
        ll dist_start_key_u_lca = 0;
        for (int key_u_lca = start; ; key_u_lca = moveFrom[key][key_u_lca]) {
            for (auto& [v, w] : g[key_u_lca]) {
                if (v == moveTo[key_u_lca][start]) continue;
                if (v == moveTo[key_u_lca][key]) continue;

                const auto [furthest, opt] = furthestDistForbid[v][key_u_lca];
                // cout << furthest << '\n';

                // cout << start + 1 << ' ' << key + 1 << ' ' << trap + 1 << ' ' << key_u_lca + 1 << ' ' << furthest << ' ' << opt + 1 << '\n';

                ll triplePath = 0;
                if (moveTo[KEY_TRAP_LCA][opt] == KEY_TRAP_LCA_TO_KEY)
                    triplePath = distOf[KEY_TRAP_LCA][key_u_lca];

                ans = min(ans, 2 * triplePath - furthest - w - dist_start_key_u_lca);
            }

            if (key_u_lca == key) break;
            dist_start_key_u_lca += distOf[key_u_lca][moveFrom[key][key_u_lca]];
        }

        // ll ans = LLONG_MAX;
        // auto dfs = [&](auto&& dfs, int u, int p, int key_x_lca, ll dist) -> void {
        //     ll triplePath = 0;
        //     if (moveTo[KEY_TRAP_LCA][u] == moveTo[KEY_TRAP_LCA][key])
        //         triplePath = distOf[KEY_TRAP_LCA][key_x_lca];

        //     ans = min(ans, -dist + 2 * triplePath);

        //     for (auto& [v, w] : g[u]) {
        //         if (v == p) continue;
        //         if (moveFrom[key][u] == v)
        //             dfs(dfs, v, u, v, dist + w);
        //         else
        //             dfs(dfs, v, u, key_x_lca, dist + w);
        //     }
        // };
        // dfs(dfs, start, start, start, 0);

        cout << distAll + ans << '\n';
    }
}

signed main() {
#ifndef LOCAL
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
#endif
    cout << fixed << setprecision(10);
    int T = 1;
    // cin >> T;
    while (T--) solve();
    return 0;
}

Details

In file included from /usr/include/c++/13/string:43,
                 from /usr/include/c++/13/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:52,
                 from answer.code:4:
/usr/include/c++/13/bits/allocator.h: In destructor ‘std::_Vector_base<std::vector<std::pair<int, int> >, std::allocator<std::vector<std::pair<int, int> > > >::_Vector_impl::~_Vector_impl()’:
/usr/include/c++/13/bits/allocator.h:184:7: error: inlining failed in call to ‘always_inline’ ‘std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = std::vector<std::pair<int, int> >]’: target specific option mismatch
  184 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/13/vector:66,
                 from /usr/include/c++/13/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:53:
/usr/include/c++/13/bits/stl_vector.h:133:14: note: called from here
  133 |       struct _Vector_impl
      |              ^~~~~~~~~~~~