Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)相关的知识,希望对你有一定的参考价值。
题意
交互题,给定一个数字 n n n表示树的节点数
你需要在不多于 n + 1 2 \\frac{n+1}{2} 2n+1次询问后得到树上的每一条边
每次询问你可以给出一个点 x x x,然后会返回 x x x到每个点的距离
第一次询问没有树上的任何信息,所以选任何一个点都是一样的,不妨选择点 1 1 1
那么得到数组 d i s i dis_i disi表示 1 1 1到 i i i的最短路为 d i s i dis_i disi
现在怎么做??
若过可以询问 n n n次,那么对每个点询问一次得到相邻边即可
现在只能询问 ⌈ x ⌉ 2 \\frac{ \\lceil x \\rceil}{2} 2⌈x⌉次,于是我们要尽量避免相邻点的询问
于是我们可以以节点 1 1 1为根,以 d i s i dis_i disi的奇偶性分层
奇数为一组,偶数为一组形成一个二分图
若奇数节点的和小于等于 ⌈ n ⌉ 2 \\frac{\\lceil n \\rceil}{2} 2⌈n⌉,显然询问所有奇数点即可
否则,偶数节点的和小于 ⌈ n ⌉ 2 \\frac{\\lceil n \\rceil}{2} 2⌈n⌉,而询问次数剩下 ⌈ n ⌉ 2 − 1 \\frac{\\lceil n \\rceil}{2}-1 2⌈n⌉−1
显然不管 n n n为奇数或偶数都是满足的,询问所有偶数节点即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e3+10;
int dis1[maxn],dis2[maxn],l[maxn],r[maxn],top,n;
bool ok[maxn][maxn];
void add(int x,int y)
{
if( ok[x][y] ) return;
ok[x][y] = ok[y][x] = 1;
l[++top] = x, r[top] = y;
}
void get(int x,int dis[] )
{
cout << "? " << x << endl;
for(int i=1;i<=n;i++) cin >> dis[i];
for(int i=1;i<=n;i++)
if( dis[i]==1 ) add( x,i );
}
int main()
{
ios::sync_with_stdio(false);
cin >> n;
get( 1,dis1 );
int even = 1, op = 0;//开始默认访问偶数层
for(int i=2;i<=n;i++)
if( !( dis1[i]&1 ) ) even++;//统计偶数层节点个数
if( even>(n+1)/2 ) op = 1;
for(int i=2;i<=n;i++)
if( ( dis1[i]&1 )==op ) get( i,dis2 );
cout << "!\\n";
for(int i=1;i<=top;i++)
cout << l[i] << " " << r[i] << endl;
return 0;
}
以上是关于Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)
Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) E. Lost Array(构造)
Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) B. Histogram Ugliness(贪心)
Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)
D. Lost Tree树的二分图性质——Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)
D. Lost Tree树的二分图性质——Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)