이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "swap.h"
#include <iostream>
#include <vector>
#include <algorithm>
#define f first
#define s second
using namespace std;
const int NMAX = 1e5, MMAX = 2e5, inf = 2e9;
int n, m, tata[NMAX+10], rang[NMAX+10], mini[3][NMAX+10], costTata[NMAX+10], dp[20][NMAX+10], dp1[20][NMAX+10], dp2[20][NMAX+10], nivel[NMAX+10];
int dp_sus[NMAX+10], dpCycle[NMAX+10];
pair <int, int> dp_jos[2][NMAX+10];
vector <pair <int, int> > nod[NMAX+10], tree[NMAX+10];
struct Kruskal{
    int n1, n2, cost;
}K[MMAX+10];
inline bool cmp(Kruskal a, Kruskal b){
    return a.cost < b.cost;
}
int findDaddy(int x){
    int r = x, y = x;
    while(r != tata[r])
        r = tata[r];
    while(x != tata[x]){
        y = tata[x];
        tata[x] = r;
        x = y;
    }
    return r;
}
void unite(int x, int y){
    if(rang[x] < rang[y])
        tata[x] = y;
    else
        tata[y] = x;
    if(rang[x] == rang[y])
        rang[x]++;
}
void dfs(int x, int p = 0){
    dp[0][x] = p;
    nivel[x] = nivel[p] + 1;
    for(auto u : nod[x])
        if(u.f != p){
            for(int t=0; t<3; t++)
                if(mini[t][x] > u.s){
                    for(int t1=2; t1>t; t1--)
                        mini[t1][x] = mini[t1-1][x];
                    mini[t][x] = u.s;
                    break;
                }
        }
    for(auto u : tree[x])
        if(u.f != p){
            dfs(u.f, x);
            costTata[u.f] = u.s;
        }
}
void dfs1(int x, int p = 0){
    dp_jos[0][x].f = dp_jos[0][x].s = dp_jos[1][x].f = dp_jos[1][x].s = inf;
    dpCycle[x] = inf;
    for(auto u : nod[x])
        if(dp[0][u.f] != x && dp[0][x] != u.f)
            dpCycle[x] = min(dpCycle[x], u.s);
    for(auto u : tree[x])
        if(u.f != p){
            dfs1(u.f, x);
            if(max(u.s, min(dp_jos[0][u.f].f, mini[1][u.f])) < dp_jos[0][x].f){
                dp_jos[1][x] = dp_jos[0][x];
                dp_jos[0][x] = {max(u.s, min(dp_jos[0][u.f].f, mini[1][u.f])), u.s};
            }
            else if(max(u.s, min(dp_jos[0][u.f].f, mini[1][u.f])) < dp_jos[1][x].f){
                dp_jos[1][x] = {max(u.s, min(dp_jos[0][u.f].f, mini[1][u.f])), u.s};
            }
            dpCycle[x] = min(dpCycle[x], dpCycle[u.f]);
        }
}
void dfs2(int x, int p = 0){
    dp_sus[x] = min(min(mini[2][x], max(mini[1][x], costTata[x])), max(costTata[x], dp_sus[dp[0][x]]));
    if(dp_jos[0][dp[0][x]].s == x)
        dp_sus[x] = min(dp_sus[x], max(costTata[x], dp_jos[1][dp[0][x]].f));
    else
        dp_sus[x] = min(dp_sus[x], max(costTata[x], dp_jos[0][dp[0][x]].f));
    for(auto u : tree[x])
        if(u.f != p)
            dfs2(u.f, x);
}
void buildStramosi(){
    for(int i=1; i<=n; i++){
        if(costTata[i] != mini[0][dp[0][i]])
            dp2[0][i] = mini[0][dp[0][i]];
        else
            dp2[0][i] = mini[1][dp[0][i]];
        dp1[0][i] = costTata[i];
    }
    for(int bit=1; (1<<bit)<=n; bit++)
        for(int i=1; i<=n; i++){
            dp[bit][i] = dp[bit-1][dp[bit-1][i]];
            dp1[bit][i] = max(dp1[bit-1][i], dp1[bit-1][dp[bit-1][i]]);
            dp2[bit][i] = min(dp2[bit-1][i], dp2[bit-1][dp[bit-1][i]]);
        }
}
pair <int, int> lca(int x, int y){
    if(nivel[x] < nivel[y])
        swap(x, y);
    int dif = nivel[x] - nivel[y], ans = 0;
    for(int bit=0; (1<<bit)<=dif; bit++)
        if(dif & (1 << bit)){
            ans = max(ans, dp1[bit][x]);
            x = dp[bit][x];
        }
    if(x == y)
        return {x, ans};
    for(int bit=19; bit>=0; bit--)
        if(dp[bit][x] != dp[bit][y]){
            ans = max(ans, max(dp1[bit][x], dp1[bit][y]));
            x = dp[bit][x];
            y = dp[bit][y];
        }
    return {dp[0][x], max(ans, max(dp1[0][x], dp1[0][y]))};
}
int findStr(int x, int k){
    for(int bit=0; (1<<bit)<=k; bit++)
        if(k & (1 << bit))
            x = dp[bit][x];
    return x;
}
int minLant(int x, int k){
    int ans = inf;
    for(int bit=0; (1<<bit)<=k; bit++)
        if(k & (1 << bit)){
            ans = min(ans, dp2[bit][x]);
            x = dp[bit][x];
        }
    return ans;
}
void init(int N, int M, std::vector<int> U, std::vector<int> V, std::vector<int> W){
    n = N;
    m = M;
    for(int i=1; i<=n; i++)
        tata[i] = i, rang[i] = 1;
    for(int i=0; i<m; i++){
        int nod1 = U[i] + 1, nod2 = V[i] + 1, cost = W[i];
        nod[nod1].push_back({nod2, cost});
        nod[nod2].push_back({nod1, cost});
        K[i+1] = {nod1, nod2, cost};
    }
    sort(K+1, K+m+1, cmp);
    for(int i=1; i<=m; i++){
        int val1 = findDaddy(K[i].n1), val2 = findDaddy(K[i].n2);
        if(val1 != val2){
            unite(val1, val2);
            tree[K[i].n1].push_back({K[i].n2, K[i].cost});
            tree[K[i].n2].push_back({K[i].n1, K[i].cost});
        }
    }
    for(int i=1; i<=n; i++)
        mini[0][i] = mini[1][i] = mini[2][i] = inf;
    costTata[1] = inf;
    dfs(1);
    dfs1(1);
    dfs2(1);
    buildStramosi();
}
int getMinimumFuelCapacity(int X, int Y){
    int x = X + 1, y = Y + 1;
    pair <int, int> LCA = lca(x, y);
    int val1 = LCA.s, val2 = inf;
    if(findStr(y, nivel[y] - nivel[LCA.f]) == x)
        swap(x, y);
    if(findStr(x, nivel[x] - nivel[LCA.f]) == y){
        val2 = mini[1][x];
        int val = nivel[x] - nivel[LCA.f] - 1, str = findStr(x, val);
        val2 = min(val2, minLant(x, val));
        val2 = min(val2, dp_sus[str]);
        val2 = min(val2, dpCycle[y]);
    }
    else{
        val2 = min(dp_jos[0][x].f, dp_jos[0][y].f);
        val2 = min(val2, min(mini[1][x], mini[1][y]));
        int val = nivel[x] - nivel[LCA.f] - 1;
        val2 = min(val2, minLant(x, val));
        val = nivel[y] - nivel[LCA.f] - 1;
        val2 = min(val2, minLant(y, val));
        val2 = min(val2, min(mini[2][LCA.f], costTata[LCA.f]));
        val2 = min(val2, dpCycle[x]);
        val2 = min(val2, dpCycle[y]);
    }
    if(val2 == inf)
        return -1;
    return max(val1, val2);
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |