This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "highway.h"
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 1012345678;
vector<int> shortest_path(int src, const vector<vector<int> > &G) {
	int N = G.size();
	queue<int> que;
	que.push(src);
	vector<int> dist(N, inf);
	dist[src] = 0;
	while(!que.empty()) {
		int u = que.front(); que.pop();
		for(int i : G[u]) {
			if(dist[i] == inf) {
				dist[i] = dist[u] + 1;
				que.push(i);
			}
		}
	}
	return dist;
}
void find_pair(int N, std::vector<int> U, std::vector<int> V, int A, int B) {
	// subtask 1, 2, 3, 4, 5, 6 (90 points)
	// step #0. calculate basic distance
	int M = U.size();
	int D = ask(vector<int>(M, 0)) / A;
	// step #1. binary search connectivity
	int lt = -1, rt = N;
	while(rt - lt > 1) {
		int mt = (lt + rt) >> 1;
		vector<int> w(M);
		for(int i = 0; i < M; ++i) {
			w[i] = (U[i] <= mt && V[i] <= mt ? 0 : 1);
		}
		long long res = ask(w);
		if(res == 1LL * D * A) rt = mt;
		else lt = mt;
	}
	int cutvert = rt;
	// step #2. find either S or T
	vector<vector<int> > G2(cutvert + 1);
	for(int i = 0; i < M; ++i) {
		if(U[i] <= cutvert && V[i] <= cutvert) {
			G2[U[i]].push_back(V[i]);
			G2[V[i]].push_back(U[i]);
		}
	}
	vector<int> dc = shortest_path(cutvert, G2);
	vector<int> perm(cutvert + 1);
	for(int i = 0; i <= cutvert; ++i) {
		perm[i] = i;
	}
	sort(perm.begin(), perm.end(), [&](int i, int j) { return dc[i] != dc[j] ? dc[i] < dc[j] : i < j; });
	vector<int> iperm(cutvert + 1);
	for(int i = 0; i <= cutvert; ++i) {
		iperm[perm[i]] = i;
	}
	int ls = -1, rs = cutvert + 1;
	while(rs - ls > 1) {
		int ms = (ls + rs) >> 1;
		vector<int> w(N);
		for(int i = 0; i < M; ++i) {
			if(U[i] <= cutvert && V[i] <= cutvert && iperm[U[i]] <= ms && iperm[V[i]] <= ms) {
				w[i] = 0;
			}
			else {
				w[i] = 1;
			}
		}
		long long res = ask(w);
		if(res == 1LL * D * A) rs = ms;
		else ls = ms;
	}
	int S = perm[rs];
	// step #3. find both S and T
	vector<int> ds = shortest_path(S, G2);
	vector<int> perm2(cutvert + 1);
	for(int i = 0; i <= cutvert; ++i) {
		perm2[i] = i;
	}
	sort(perm2.begin(), perm2.end(), [&](int i, int j) { return ds[i] != ds[j] ? ds[i] < ds[j] : i < j; });
	vector<int> iperm2(cutvert + 1);
	for(int i = 0; i <= cutvert; ++i) {
		iperm2[perm2[i]] = i;
	}
	int lg = -1, rg = cutvert + 1;
	while(rg - lg > 1) {
		int mg = (lg + rg) >> 1;
		vector<int> w(M);
		for(int i = 0; i < M; ++i) {
			if(U[i] <= cutvert && V[i] <= cutvert && iperm2[U[i]] <= mg && iperm2[V[i]] <= mg) {
				w[i] = 0;
			}
			else {
				w[i] = 1;
			}
		}
		long long res = ask(w);
		if(res == 1LL * D * A) rg = mg;
		else lg = mg;
	}
	int T = perm2[rg];
	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... |