Submission #1225937

#TimeUsernameProblemLanguageResultExecution timeMemory
1225937SpyrosAlivSwapping Cities (APIO20_swap)C++20
0 / 100
2094 ms12292 KiB
#include "swap.h"
#include <bits/stdc++.h>
using namespace std;

const int MN = 1e5+5;
const int INF = 1e9+10;
int n, m;
int par[MN], sz[MN];
vector<tuple<int, int, int>> edges;
vector<vector<int>> g;
vector<bool> av, inPath, vis;
int ans1 = 0, ans2 = 0;
bool cyc = false;

int find(int u) {
    if (par[u] == u) return u;
    return par[u] = find(par[u]);
}

void merge(int e) {
    int u = get<1>(edges[e]);
    int v = get<2>(edges[e]);
    u = find(u);
    v = find(v);
    if (u == v) return;
    if (sz[u] > sz[v]) swap(u, v);
    par[u] = v;
    sz[v] += sz[u];
}

bool dfs1(int node, int targ) {
    vis[node] = true;
    if (node == targ) {
        inPath[node] = true;
        return true;
    }
    for (auto e: g[node]) {
        if (!av[e]) continue;
        int v = get<2>(edges[e]) ^ get<1>(edges[e]) ^ node;
        if (!vis[v]) dfs1(v, targ);
        inPath[node] = inPath[node] || inPath[v];
    }
    return inPath[node];
}

void init(int N, int M, vector<int> U, vector<int> V, vector<int> W) {
    n = N;
    m = M;
    for (int i = 0; i < m; i++) {
        edges.push_back({W[i], U[i], V[i]});
    }
    sort(edges.begin(), edges.end());
    g.resize(n);
    for (int i = 0; i < m; i++) {
        int u = get<1>(edges[i]);
        int v = get<2>(edges[i]);
        g[u].push_back(i);
        g[v].push_back(i);
    }
}

int getMinimumFuelCapacity(int X, int Y) {
    int a = X, b = Y;
    ans1 = ans2 = INF;
    for (int i = 0; i < n; i++) {
        par[i] = i;
        sz[i] = 1;
    }
    av.assign(m, false);
    bool passedPath = false;
    for (int i = 0; i < m; i++) {
        av[i] = true;
        merge(i);
        if (!passedPath) {
            ans1 = get<0>(edges[i]);
            if (find(a) != find(b)) continue;
            inPath.assign(n, false);
            vis.assign(n, false);
            dfs1(a, b);
            vector<int> cand;
            int other = INF;
            for (int u = 0; u < n; u++) {
                if (!inPath[u] || u == a || u == b) continue;
                int tot = 0;
                vector<int> alt;
                for (auto e: g[u]) {
                    int w = get<0>(edges[e]);
                    int v = u ^ get<1>(edges[e]) ^ get<2>(edges[e]);
                    if (inPath[v]) {
                        alt.push_back(w);
                        tot++;
                    }
                    else cand.push_back(w);
                }
                if (tot < 3) continue;
                sort(alt.begin(), alt.end());
                other = min(other, alt[2]);
            }
            cand.push_back(other);
            sort(cand.begin(), cand.end());
            ans1 = max(ans1, cand[0]);
            passedPath = true;
            for (int i = 0; i < n; i++) {
                par[i] = i;
                sz[i] = 1;
            }
            for (int u = 0; u < n; u++) {
                if (!inPath[u]) continue;
                int tot = 0;
                for (auto e: g[u]) {
                    int w = get<0>(edges[e]);
                    int v = u ^ get<1>(edges[e]) ^ get<2>(edges[e]);
                    if ((inPath[u] && inPath[v]) || (inPath[u] && u != a && u != b) || (inPath[v] && v != a && v != b)) {
                        av[e] = false;
                    }
                }
            }
            for (int e = 0; e < m; e++) {
                if (av[e]) merge(e);
            }
        }
        else {
            int u = get<1>(edges[i]);
            int v = get<2>(edges[i]);
            ans2 = get<0>(edges[i]);
            if (find(a) != find(b)) continue;
            break;
        }
    }
    int ans = ans1;
    if (find(a) == find(b)) ans = min(ans1, ans2);
    if (ans == INF) return -1;
    return 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...