| # | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 | 
|---|---|---|---|---|---|---|---|
| 1283906 | duckindog | 밀림 점프 (APIO21_jumps) | C++20 | 0 ms | 0 KiB | 
#include <bits/stdc++.h>
#include "split.h"
using namespace std;
const int N = 100'000 + 10;
int n;
pair<int, int> c[3];
vector<int> ad[N];
vector<int> ret;
int sz[N];
int low[N], num[N], it;
void initDFS(int u, int p = -1) { 
    sz[u] = 1;
    low[u] = num[u] = ++it;
    for (const auto& v : ad[u]) { 
        if (v == p) continue;
        if (num[v]) low[u] = min(low[u], num[v]);
        else { 
            initDFS(v, u);
            sz[u] += sz[v];
            low[u] = min(low[u], low[v]);
        }
    }
}
void doColor(int u, int p, int idx) { 
    if (c[idx].second <= 0 || ret[u]) return;
    c[idx].second -= 1;
    
    ret[u] = c[idx].first;
    for (const auto& v : ad[u]) { 
        if (v == p || num[v] < num[u]) continue;
        doColor(v, u, idx);
    }
}
bool doneColor = false;
void dfs(int u, int p = - 1) { 
    if (doneColor) return;
    for (const auto& v : ad[u]) { 
        if (v == p || num[v] <= num[u]) continue;
        dfs(v, u);
        if (doneColor) return;
    }
    vector<int> tmp;
    int curSZ = sz[u];
    for (const auto& v : ad[u]) { 
        if (v == p) continue;
        if (num[v] < low[u] && curSZ > c[0].first + c[2].first && curSZ - sz[v] >= c[0].first) { 
            curSZ -= sz[v];
        } else tmp.push_back(v);
    }
    if (curSZ <= c[0].first + c[2].first) { 
        swap(ad[u], tmp);
        doColor(u, p, 0);
        doColor(p, u, 1);
        doneColor = true;
    }
}
vector<int> find_split(int _n, int _a, int _b, int _c, vector<int> _p, vector<int> _q) {
    { // input
        n = _n;
        for (int i = 0; i < (int)_p.size(); ++i) { 
            int u = _p[i], v = _q[i];
            ad[u].push_back(v);
            ad[v].push_back(u);
        }
        c[0] = {_a, 1};
        c[1] = {_b, 2};
        c[2] = {_c, 3};
        sort(c, c + 3);
    }
    ret.resize(n, 0);
    initDFS(0);
    dfs(0);
    if (doneColor) { 
        for (auto& x : ret) if (!x) x = c[2].second;
    }
    return ret;
}
