QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#758081#9570. Binary Treewht11RE 0ms0kbC++206.0kb2024-11-17 15:40:182024-11-17 15:40:19

Judging History

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

  • [2024-11-17 15:40:19]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-11-17 15:40:18]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

int query(int x, int y)
{
    cout << "? " << x << " " << y << endl;
    cout.flush();
    cin >> x;
    return x;
}

vector<int> adj[100005];
bool vis[100005];
int T, n;
int sz;

void add(int x, int y)
{
    // cout << "add " << x << " " << y << endl;
    adj[x].push_back(y);
    adj[y].push_back(x);
}

void Free(int x, int fa)
{
    if (!vis[x])
        sz--;
    vis[x] = true;
    for (int y : adj[x])
    {
        if (y == fa)
            continue;
        Free(y, x);
    }
}

int mn, centre = 0;
int sum[100005];
int tot = 0;
int father[100005];

void dfs(int u, int fa)
{
    // cout << "123\n";
    father[u] = fa;
    if (vis[u])
    {
        sum[u] = 0;
        return;
    }
    sum[u] = 1;
    for (auto v : adj[u])
    {
        if (v == fa)
            continue;
        dfs(v, u);
        sum[u] += sum[v];
    }
}

void get_centre(int u, int fa)
{
    if (vis[u])
        return;
    int mx = 0;
    for (auto v : adj[u])
    {
        if (v == fa)
            continue;
        get_centre(v, u);
        mx = max(mx, sum[v]);
    }
    if (u != fa)
    {
        mx = max(mx, tot - sum[u]);
    }
    // cout << u << " " << mx << endl;
    if (mx < mn)
    {
        mn = mx;
        centre = u;
    }
}

int Find(int S)
{
    // cout << "haha\n";
    mn = 1e9;
    dfs(S, S);
    tot = sum[S];
    get_centre(S, S);
    // cout << centre << " " << mn << endl;
    return centre;
}

vector<int> get_adj(int x)
{
    vector<int> ret;
    for (int i : adj[x])
    {
        if (!vis[i])
            ret.push_back(i);
    }
    // for(int x: ret) cout << x << "#";
    return ret;
}

int main()
{
    cin >> T;
    while (T--)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            vis[i] = false;
        for (int i = 1; i <= n; i++)
            adj[i].clear();
        for (int i = 1; i <= n; i++)
        {
            int l, r;
            cin >> l >> r;
            if (l)
                add(i, l);
            if (r)
                add(i, r);
        }

        sz = n;
        while (sz > 3)
        {
            // cout << "alive: \n";
            // for(int i=1;i<=n;i++){
            //     if(!vis[i]) cout << i << " ";
            // }
            int alive = -1;
            for (int i = 1; i <= n; i++)
                if (!vis[i])
                {
                    alive = i;
                    break;
                }

            int x = Find(alive);
            vector<int> v = get_adj(x);

            if (v.size() == 2)
            {
                int a = v[0], b = v[1];
                int res = query(a, b);

                if (res == 0)
                {
                    Free(b, x);
                    if (v.size() > 2)
                    {
                        int c = v[2];
                        Free(c, x);
                    }
                    vis[x] = true;
                    sz--;
                }
                else if (res == 1)
                {
                    Free(b, x);
                    Free(a, x);
                }
                else
                {
                    // res = 2
                    Free(a, x);
                    if (v.size() > 2)
                    {
                        int c = v[2];
                        Free(c, x);
                    }
                    vis[x] = true;
                    sz--;
                }
            }
            else if (v.size() == 3)
            {
                int a = v[0], b = v[1], c = v[2];
                vector<pair<int, int>> v1;
                if (a == father[x])
                    v1.push_back({tot - sum[x], a});
                else
                    v1.push_back({sum[a], a});
                if (b == father[x])
                    v1.push_back({tot - sum[x], b});
                else
                    v1.push_back({sum[b], b});
                if (c == father[x])
                    v1.push_back({tot - sum[x], c});
                else
                    v1.push_back({sum[c], c});
                sort(v1.rbegin(), v1.rend());

                a = v1[0].second, b = v1[1].second, c = v1[2].second;
                int res = query(a, b);

                if (res == 0)
                {
                    Free(b, x);
                    Free(c, x);
                    vis[x] = true;
                    sz--;
                }
                else if (res == 1)
                {
                    Free(b, x);
                    Free(a, x);
                }
                else
                {
                    // res = 2
                    Free(a, x);
                    Free(c, x);
                    vis[x] = true;
                    sz--;
                }
            }
            else
            {
                throw exception();
            }
        }

        int ans = -1;
        vector<int> v;
        for (int i = 1; i <= n; i++)
            if (!vis[i])
                v.push_back(i);

        if (v.size() == 1)
        {
            ans = v[0];
        }
        else if (v.size() == 2)
        {
            int x = v[0], y = v[1];
            int res = query(x, y);
            if (res == 0)
                ans = x;
            else
                ans = y;
        }
        else if (v.size() == 3)
        {
            int x = v[0], y = v[1];
            int mid = Find(x);
            x = y = -1;
            for (int i : v)
            {
                if (i != mid)
                {
                    if (x == -1)
                        x = i;
                    else
                        y = i;
                }
            }

            int res = query(x, y);
            if (res == 0)
                ans = x;
            else if (res == 1)
                ans = mid;
            else
                ans = y;
        }

        cout << "! " << 4 << endl;
        cout.flush();
    }
}

详细

Test #1:

score: 0
Runtime Error

input:

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

output:

? 3 5
? 1 2
! 4

result: