Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree

该博客介绍了一种算法,通过不超过n/2次询问,获取树中任意两点之间的距离,进而重建树的结构。首先以1为根节点进行询问,获取所有节点的深度,然后根据深度的奇偶性将节点染色,并找到连接节点的边。最终输出树的边,揭示其结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Lost Tree

题意

先给定一个树,你每次可以询问某个点到 n n n 个点的距离,要求通过最多 ⌈ n 2 ⌉ \left \lceil \frac{n}{2} \right \rceil 2n 次询问,得到树的结构。

题解
  • 1 1 1 作为根节点,先询问根到其他点的距离,就得到了每个点的深度;
  • 把所有 n n n 个点染两种颜色,也就是深度奇偶相同的点是同一种颜色;
  • 如果距离为 1 1 1 那么两个点之间有一条边;
  • 询问颜色数少的节点。
代码
#include<bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 5;
int n, ans[maxn][maxn];
void query(int u) {
    cout << "? " << u << endl;
    rep(i, 1, n) {
        cin >> ans[u][i];
        ans[i][u] = ans[u][i];
    }
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n;
    query(1);
    vector<int> cnt(2);
    rep(i, 1, n) cnt[ans[1][i] & 1]++;
    int q = (cnt[1] < cnt[0] ? 1 : 0);
    rep(i, 2, n) if (ans[1][i] % 2 == q) query(i);
    cout << "!" << endl;
    rep(i, 1, n) rep(j, i + 1, n)
        if (ans[i][j] == 1) cout << i << " " << j << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值