이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#include "highway.h"
using namespace std;
tuple<vector<int>, vector<int>, vector<int>> bfs(
    int N, int M, vector<vector<pair<int, int>>> &adj, vector<int> srcs
) {
    vector<int> dist(N, -1);
    queue<int> q;
    for(int u : srcs) {
        dist[u] = 0;
        q.push(u);
    }
    vector<int> tree_edges;
    vector<int> cross_edges_mask(M, true);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(auto [v, i] : adj[u]) {
            if(dist[v] == -1) {
                dist[v] = dist[u] + 1;
                cross_edges_mask[i] = false;
                tree_edges.push_back(i);
                q.push(v);
            }
        }
    }
    vector<int> cross_edges;
    for(int i = 0; i < M; i++) {
        if(cross_edges_mask[i]) {
            cross_edges.push_back(i);
        }
    }
    return {dist, tree_edges, cross_edges};
}
int find_first(vector<int> edges, int l, int r, int m, int64_t dist_heavy) {
    int found = -1, start = l;
    while(l <= r) {
        int mid = (l + r) >> 1;
        vector<int> mask(m, 1);
        for(int i = start; i <= mid; i++) {
            mask[edges[i]] = 0;
        }
        if(ask(mask) < dist_heavy) {
            r = mid - 1;
            found = mid;
        } else {
            l = mid + 1;
        }
    }
    return found;
}
pair<int, int> solve(
    vector<int> main_edge, int l, int r, int m, int64_t dist_heavy,
    int64_t dist_light
) {
    if(l == r) {
        return {l, -1};
    }
    int mid = (l + r) >> 1;
    vector<int> mask(m, 1);
    for(int i = l; i <= mid; i++) {
        if(main_edge[i] != -1) {
			mask[main_edge[i]] = 0;
		}
	}
    int64_t dist_l = ask(mask);
    if(dist_l == dist_light) {
        return solve(main_edge, l, mid, m, dist_heavy, dist_light);
    } else if(dist_l == dist_heavy) {
        return solve(main_edge, mid + 1, r, m, dist_heavy, dist_light);
    } else {
        int s = find_first(main_edge, l, mid, m, dist_heavy);
        int t = find_first(main_edge, mid + 1, r, m, dist_heavy);
        return {s, t};
    }
}
void find_pair(int N, std::vector<int> U, std::vector<int> V, int A, int B) {
    vector<vector<pair<int, int>>> adj;
    adj.assign(N, {});
    for(int i = 0; i < (int)U.size(); i++) {
        adj[U[i]].push_back({V[i], i});
        adj[V[i]].push_back({U[i], i});
    }
    auto [dist, tree_edges, cross_edges] = bfs(N, U.size(), adj, {0});
    // 1 query
    int64_t dist_heavy = ask(vector<int>(U.size(), 1));
    // ceil(log2(M - N)) queries. Worst case 16 queries
    int found = find_first(
        cross_edges, 0, (int)cross_edges.size() - 1, U.size(), dist_heavy
    );
    if(found != -1) {
        // reroot needed to guarantee that shortest path is on bfs tree
        auto [new_dist, new_tree_edges, _] =
            bfs(N, U.size(), adj,
                {U[cross_edges[found]], V[cross_edges[found]]});
		new_tree_edges.push_back(found);
        tree_edges = new_tree_edges;
        dist = new_dist;
    }
    // 2 * ceil(log2(N) - 1) + 1 queries.
    // Worst case 33 queries
    vector<int> main_edge(N, -1);
    for(auto i : tree_edges) {
        int u = U[i], v = V[i];
        if(dist[u] > dist[v]) {
            swap(u, v);
        }
        main_edge[v] = i;
    }
    int root = -1;
    for(int i = 0; i < N; i++) {
        if(main_edge[i] == -1) {
            root = i;
        }
    }
    int64_t dist_light = (dist_heavy / B) * A;
    auto [s, t] = solve(main_edge, 0, N - 1, U.size(), dist_heavy, dist_light);
    
	if(s == -1) {
        s = root;
    } 
	if(t == -1) {
        t = root;
    }
    answer(s, t);
}
| # | 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... |