제출 #577912

#제출 시각아이디문제언어결과실행 시간메모리
577912JomnoiSwapping Cities (APIO20_swap)C++17
100 / 100
408 ms43292 KiB
#include <bits/stdc++.h>
#include "swap.h"
using namespace std;

const int MAX_N = 2e5 + 5;
const int INF = 1e9 + 7;

int N, M;
int parent[MAX_N];
int degree[MAX_N];
int min_weight[MAX_N];
vector <int> graph[MAX_N];
int depth[MAX_N], par[MAX_N][20];

int find_parent(int u) {
    if(u == parent[u]) {
        return u;
    }
    return parent[u] = find_parent(parent[u]);
}

void merge(int u, int v, int w) {
    bool valid = (degree[u] > 1 or degree[v] > 1);
    degree[u]++, degree[v]++;

    u = find_parent(u), v = find_parent(v);
    if(u == v) {
        min_weight[u] = min(min_weight[u], w);
        return;
    }

    N++;
    parent[v] = parent[u] = N;
    graph[N].push_back(u);
    graph[N].push_back(v);
    if(valid == true or min_weight[u] != INF or min_weight[v] != INF) {
        min_weight[N] = w;
    }
}

void dfs(int u) {
    for(int i = 1; i < 20; i++) {
        par[u][i] = par[par[u][i - 1]][i - 1];
    }
    for(auto v : graph[u]) {
        par[v][0] = u;
        depth[v] = depth[u] + 1;
        min_weight[v] = min(min_weight[v], min_weight[u]);
        dfs(v);
    }
}

int find_lca(int u, int v) {
    if(depth[u] < depth[v]) {
        swap(u, v);
    }
    for(int i = 19; i >= 0; i--) {
        if(depth[par[u][i]] >= depth[v]) {
            u = par[u][i];
        }
    }
    for(int i = 19; i >= 0; i--) {
        if(par[u][i] != par[v][i]) {
            u = par[u][i], v = par[v][i];
        }
    }
    return (u == v ? u : par[u][0]);
}

void init(int n, int m, vector <int> U, vector <int> V, vector <int> W) {
    N = n, M = m;

    vector <tuple <int, int, int>> edges;
    for(int i = 0; i < m; i++) {
        edges.emplace_back(W[i], U[i] + 1, V[i] + 1);
    }

    sort(edges.begin(), edges.end());

    fill(min_weight, min_weight + MAX_N, INF);
    iota(parent, parent + MAX_N, 0);
    for(auto [w, u, v] : edges) {
        merge(u, v, w);
    }

    depth[0] = -1;
    dfs(N);

    for(int i = 1; i <= N; i++) {
        if(min_weight[i] == INF) {
            min_weight[i] = -1;
        }
    }
}

int getMinimumFuelCapacity(int X, int Y) {
    return min_weight[find_lca(X + 1, Y + 1)];
}
#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...