Codeforces Round #746 (Div. 2) D. Hemose in ICPC ?(交互,dfs序)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #746 (Div. 2) D. Hemose in ICPC ?(交互,dfs序)相关的知识,希望对你有一定的参考价值。
给一棵 n n n个节点、边权未知的树
定义两个节点之间的距离为路径上所有边权的 g c d gcd gcd。每次你可以询问一个节点集合
然后交互程序会返回所给集合中最大的距离,求在不超过 12 12 12次询问的前提下
距离最大的两个节点的编号。( n < = 1 0 3 n<=10^3 n<=103)
先询问一次所有节点得到 m x mx mx
然后注意到 2 10 > = 1000 2^{10}>=1000 210>=1000,那么肯定与二分有关
我们处理出这棵树的 d f s dfs dfs序
直接在 d f s dfs dfs序上二分可以找到最大值的那个点 u u u
于是输出 u u u和 u u u的父亲即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int n,id,topf[maxn],dfn[maxn],father[maxn],mx;
vector<int>vec[maxn];
void dfs(int u,int fa)
{
dfn[u] = ++id; topf[id] = u; father[u] = fa;
for(auto v:vec[u] )
{
if( v==fa ) continue;
dfs( v,u );
}
}
bool isok(int x)
{
cout << "? " << x;
for(int i=1;i<=x;i++) cout << " " << topf[i];
cout << endl;
int z; cin >> z;
return z==mx;
}
int main()
{
cin >> n;
for(int i=1;i<n;i++)
{
int l,r; cin >> l >> r;
vec[l].push_back( r ); vec[r].push_back( l );
}
cout << "? " << n;
for(int i=1;i<=n;i++) cout << " " << i;
cout << endl;
cin >> mx;
dfs( 1,0 );
int l = 2, r = n, ans = 0;
while( r>=l )
{
int mid = l+r>>1;
if( isok(mid) ) r = mid-1, ans = mid;
else l = mid+1;
}
cout << "! ";
cout << topf[ans] << " " << father[topf[ans]] << endl;
}
以上是关于Codeforces Round #746 (Div. 2) D. Hemose in ICPC ?(交互,dfs序)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #746 (Div. 2)(A,B,C)
Codeforces Round #746 (Div. 2) C. Bakry and Partitioning
Codeforces Round #746 (Div. 2) 题解
Codeforces Round #746 (Div. 2)A-C