QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#728351#9570. Binary Treeucup-team045#TL 1ms3812kbC++203.4kb2024-11-09 15:01:072024-11-09 15:01:10

Judging History

你现在查看的是最新测评结果

  • [2024-11-09 15:01:10]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3812kb
  • [2024-11-09 15:01:07]
  • 提交

answer

#include<iostream>
#include<cstring>
#include<vector>
#include<array>
#include<algorithm>
#include<numeric>
using namespace std;
using LL = long long;

int main(){

// #ifdef LOCAL
//     freopen("data.in", "r", stdin);
//     freopen("data.out", "w", stdout);
// #endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    auto ask = [&](int x, int y){
        cout << "? " << x << ' ' << y << endl;
        int t;
        cin >> t;
        return t;
    };

    int T;
    cin >> T;
    while(T--){
        int n;
        cin >> n;
        vector<int> pt(n);
        iota(pt.begin(), pt.end(), 1);
        vector<pair<int, int> > edge;
        
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < 2; j++){
                int x;
                cin >> x;
                if (x){
                    edge.push_back({i, x});
                }
            }
        }
        
        while(pt.size() > 1){
            if (pt.size() == 2){
                if (ask(pt[0], pt[1]) == 0){
                    pt = {pt[0]};
                }
                else{
                    pt = {pt[1]};
                }
                break;
            }
            
            vector<bool> v(n + 1);
            for(auto x : pt) v[x] = true;
            vector<vector<int> > g(n + 1);
            for(auto [x, y] : edge){
                if (v[x] and v[y]){
                    g[x].push_back(y);
                    g[y].push_back(x);
                }
            }

            vector<int> sz(n + 1), fa(n + 1);

            array<int, 3> best;
            int mn = 0;

            auto dfs = [&](auto &&dfs, int u) -> void {
                sz[u] = 1;
                vector<int> sons;
                for(auto j : g[u]){
                    if (!v[j] or j == fa[u]) continue;
                    sons.push_back(j);
                    fa[j] = u;
                    dfs(dfs, j);
                    sz[u] += sz[j];
                }
                if (sons.size() == 2){
                    int sz1 = sz[sons[0]];
                    int sz2 = sz[sons[1]];
                    int sz3 = pt.size() - sz1 - sz2;
                    int t = min({sz1, sz2, sz3});
                    if (t > mn){
                        mn = t;
                        best = {sons[0], u, sons[1]};
                    }
                }
                if (fa[fa[u]] != 0){
                    int sz1 = sz[u];
                    int sz2 = sz[fa[u]] - sz[u];
                    int sz3 = pt.size() - sz1 - sz2;
                    int t = min({sz1, sz2, sz3});
                    if (t > mn){
                        mn = t;
                        best = {u, fa[u], fa[fa[u]]};
                    }
                }
            };

            int root = 0;
            while(g[pt[root]].size() == 3) root += 1;
            root = pt[root];
            dfs(dfs, root);
            int t = best[ask(best[0], best[2])];
            v[best[0]] = v[best[1]] = v[best[2]] = false;
            v[t] = true;

            pt.clear();

            auto dfs1 = [&](auto &&dfs1, int u, int fa) -> void {
                pt.push_back(u);
                for(auto j : g[u]){
                    if (!v[j] or j == fa) continue;
                    dfs1(dfs1, j, u);
                }
            };

            dfs1(dfs1, t, -1);
        }
        cout << "! " << pt[0] << endl;
    }

}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3812kb

input:

2
5
0 0
1 5
2 4
0 0
0 0
2
0
2
0 2
0 0
2

output:

? 5 3
? 3 4
! 3
? 1 2
! 2

result:

ok OK (2 test cases)

Test #2:

score: -100
Time Limit Exceeded

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
1
2
0
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
2
2
2

output:

? 6 1
? 5 4
? 4 3
! 4
? 4 3
? 4 3
? 4 3
? 4 3

result: