QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#730357 | #9570. Binary Tree | ucup-team3924# | WA | 12ms | 3624kb | C++20 | 3.1kb | 2024-11-09 19:52:54 | 2024-11-09 19:52:55 |
Judging History
answer
#include <bits/stdc++.h>
int query(int a, int b) {
std::cout << "? " << a << " " << b << std::endl;
int x;
std::cin >> x;
return x;
}
void answer(int node) {
std::cout << "! " << node << std::endl;
}
struct Graph {
std::vector<std::vector<int>> graph;
std::vector<int> subtree;
std::vector<bool> blocked;
Graph(int n): graph(1 + n), subtree(1 + n), blocked(1 + n) {}
void predfs(int node, int father = 0) {
//std::cerr << node << "\n";
subtree[node] = 1;
for (auto it: graph[node]) {
if (it != father && !blocked[it]) {
predfs(it, node);
subtree[node] += subtree[it];
}
}
}
std::vector<int> get_subtrees(int node) {
std::vector<int> choices;
for (auto it: graph[node])
if (!blocked[it])
choices.push_back(it);
return choices;
}
int get_centroid(int root, int node, int father = 0) {
for (auto it: graph[node])
if (it != father && !blocked[it] && subtree[it] > subtree[root] / 2)
return get_centroid(root, it, node);
return node;
}
void solve(int root) {
//std::cerr << "Call from root: " << root << "\n";
predfs(root);
int c = get_centroid(root, root);
predfs(c);
std::vector<int> choices = get_subtrees(c);
if (choices.size() == 0) {
answer(root);
return;
}
// single edge
if (choices.size() == 1) {
int x = query(c, choices[0]);
if (x == 0)
answer(c);
else
answer(choices[0]);
return;
}
if (choices.size() == 2) {
int x = query(choices[0], choices[1]);
if (x == 1) {
answer(c);
return;
}
blocked[c] = true;
if (x == 0)
solve(choices[0]);
else
solve(choices[2]);
}
if (choices.size() == 3) {
std::sort(choices.begin(), choices.end(), [&](int a, int b) {
return subtree[a] > subtree[b];
});
int x = query(choices[0], choices[1]);
if (x == 0) {
blocked[c] = true;
solve(choices[0]);
return;
} else if (x == 2) {
blocked[c] = true;
solve(choices[1]);
return;
} else {
blocked[choices[0]] = blocked[choices[1]] = true;
solve(c);
return;
}
}
}
};
void solve_test() {
int n;
std::cin >> n;
Graph G(n);
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 2; j++) {
int x;
std::cin >> x;
if (x != 0) {
G.graph[x].push_back(i);
G.graph[i].push_back(x);
}
}
}
G.solve(1);
}
int main() {
int t;
std::cin >> t;
while (t--) solve_test();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3624kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 1 0 2 0 2 0 0 2
output:
? 3 1 ? 2 5 ! 2 ? 1 2 ! 2
result:
ok OK (2 test cases)
Test #2:
score: -100
Wrong Answer
time: 12ms
memory: 3616kb
input:
5555 8 2 0 8 6 0 0 3 0 0 0 7 0 0 0 5 4 0 2
output:
? 8 6 ? 5 4 ! 0
result:
wrong answer There are 2 candidates. (test case 1)