이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "highway.h"
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
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, -1);
dist[src] = 0;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i : G[u]) {
if(dist[i] == -1) {
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) {
int M = U.size();
if(M != N - 1) return;
// subtask 1, 2, 3, 4 (51 points)
vector<vector<int> > G(N);
for(int i = 0; i < M; ++i) {
G[U[i]].push_back(V[i]);
G[V[i]].push_back(U[i]);
}
// step #0. find dist(depth[S], depth[T])
int D = ask(vector<int>(M, 0)) / A;
// step #1. find max(depth[S], depth[T])
vector<int> depth = shortest_path(0, G);
int ld = -1, rd = N;
while(rd - ld > 1) {
int md = (ld + rd) / 2;
vector<int> w(M, 0);
for(int i = 0; i < M; ++i) {
if(depth[U[i]] >= md && depth[V[i]] >= md) {
w[i] = 1;
}
}
long long res = ask(w);
if(res == 1LL * D * A) rd = md;
else ld = md;
}
int sd = rd;
// step #2. find either S or T
vector<int> slist;
for(int i = 0; i < M; ++i) {
if(max(depth[U[i]], depth[V[i]]) == sd) {
slist.push_back(i);
}
}
int lid = 0, rid = slist.size();
while(rid - lid > 1) {
int mid = (lid + rid) / 2;
vector<int> w(M, 0);
for(int i = 0; i < mid; ++i) {
w[slist[i]] = 1;
}
long long res = ask(w);
if(res == 1LL * D * A) lid = mid;
else rid = mid;
}
int S = (depth[U[slist[lid]]] > depth[V[slist[lid]]] ? U[slist[lid]] : V[slist[lid]]);
// step #3. find both S and T
vector<int> dist = shortest_path(S, G);
vector<int> tlist;
for(int i = 0; i < M; ++i) {
if(max(dist[U[i]], dist[V[i]]) == D) {
tlist.push_back(i);
}
}
lid = 0, rid = tlist.size();
while(rid - lid > 1) {
int mid = (lid + rid) / 2;
vector<int> w(M, 0);
for(int i = 0; i < mid; ++i) {
w[tlist[i]] = 1;
}
long long res = ask(w);
if(res == 1LL * D * A) lid = mid;
else rid = mid;
}
int T = (dist[U[tlist[lid]]] > dist[V[tlist[lid]]] ? U[tlist[lid]] : V[tlist[lid]]);
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... |