Submission #1161828

#TimeUsernameProblemLanguageResultExecution timeMemory
1161828The_SamuraiSwapping Cities (APIO20_swap)C++20
100 / 100
308 ms41116 KiB
#include "swap.h"
#include "bits/stdc++.h"
using namespace std;
#define ff first
#define ss second

struct dsu {
    vector<int> p, size;

    void init(int n) {
        size.assign(n, 1);
        p.resize(n);
        iota(p.begin(), p.end(), 0);
    }

    int get(int a) {
        return p[a] == a ? a : p[a] = get(p[a]);
    }

    void merge(int a, int b) {
        a = get(a); b = get(b);
        if (a == b) return;
        if (size[a] > size[b]) swap(a, b);
        size[b] += size[a];
        p[a] = b;
    }
};

const int inf = 2e9, lg = 17, N = 1e5 + 5;
vector<int> needs(N, inf);
vector<vector<pair<int, int>>> g(N);
vector jump(lg, vector(N, make_pair(-1, 0)));
vector<int> tin(N), tout(N);
int n, z;

void dfs(int u) {
    for (int i = 1; i < lg and u; i++) {
        jump[i][u].ff = jump[i - 1][jump[i - 1][u].ff].ff;
        if (jump[i][u].ff == -1) break;
        jump[i][u].ss = max(jump[i - 1][u].ss, jump[i - 1][jump[i - 1][u].ff].ss);
    }
    tin[u] = ++z;
    for (auto [v, w]: g[u]) {
        if (tin[v]) continue;
        jump[0][v] = make_pair(u, w);
        dfs(v);
    }
    tout[u] = ++z;
}

bool isPar(int u, int v) { return tin[u] <= tin[v] and tout[v] <= tout[u]; }

int lca(int u, int v) {
    if (isPar(u, v)) return u;
    if (isPar(v, u)) return v;
    for (int i = lg - 1; i >= 0; i--) {
        if (jump[i][u].ff != -1 and !isPar(jump[i][u].ff, v)) {
            u = jump[i][u].ff;
        }
    }
    return jump[0][u].ff;
}

int dist(int u, int v) {
    int p = lca(u, v), res = 0;
    for (int i = lg - 1; i >= 0; i--) {
        if (jump[i][u].ff != -1 and isPar(p, jump[i][u].ff)) {
            res = max(res, jump[i][u].ss);
            u = jump[i][u].ff;
        }
        if (jump[i][v].ff != -1 and isPar(p, jump[i][v].ff)) {
            res = max(res, jump[i][v].ss);
            v = jump[i][v].ff;
        }
    }
    assert(u == p and v == p);
    return res;
}

void init(int _n, int m, std::vector<int> U, std::vector<int> V, std::vector<int> W) {
    n = _n;
    vector<pair<int, int>> vec(m);
    vector<int> cnt(n), p(n);
    vector<bool> bad(n);
    vector<vector<int>> child(n);

    for (int i = 0; i < n; i++) {
        child[i] = {i};
        p[i] = i;
    }

    for (int i = 0; i < m; i++) vec[i] = make_pair(W[i], i);
    sort(vec.begin(), vec.end());
    
    for (auto [w, i]: vec) {
        cnt[U[i]]++, cnt[V[i]]++;
        bool now = (cnt[U[i]] > 2) | (cnt[V[i]] > 2);
        int u = p[U[i]], v = p[V[i]];
        if (u == v) {
            if (bad[u]) continue;
            bad[u] = true;
            for (int x: child[u]) needs[x] = w;
            continue;
        }
        // cout << U[i] << ' ' << V[i] << ' ' << w << endl;
        g[U[i]].emplace_back(V[i], w);
        g[V[i]].emplace_back(U[i], w);

        now |= bad[u] | bad[v];
        if (now and !bad[u]) for (int x: child[u]) needs[x] = w;
        if (now and !bad[v]) for (int x: child[v]) needs[x] = w;

        if (child[u].size() > child[v].size()) swap(u, v);
        for (int x: child[u]) {
            child[v].emplace_back(x);
            p[x] = v;
        }
        child[u].clear();
        bad[v] = now;
    }
    dfs(0);
}

int getMinimumFuelCapacity(int x, int y) {
    int ans = max(needs[x], needs[y]);
    ans = max(ans, dist(x, y));
    return ans == inf ? -1 : ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...