codeforces1370F1 / F2 The Hidden Pair (Hard Version)

本文详细解析了Codeforces竞赛中题目F2的解决方案。首先,通过询问所有点找到路径上两点,接着以其中一个点为根建立树并使用二分查找确定另一端点。文章还分享了一个小技巧,通过限制最远距离范围来减少二分搜索次数。

https://codeforces.com/problemset/problem/1370/F2

先询问所有点,然后就可以得到一个u,v路径上的点,因为只有他们路径上的点的距离之和是最小的

然后以这个点rt建树,二分到rt的长度可以找到较远的那个端点v,然后通过距离相减,再询问一下除去v到rt的那个距离的点,就可以找到另一个端点

然而这个询问需要12次。。。

题解的一个小优化,最远距离最小是sumdis/2,最大是sumdis,所以区间减少了一半。。。。就可以减少一次二分。。。。

#include<bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
const int maxl=1e3+10;

int n,ans1,ans2,rt,sumdis;
vector <int> e[maxl];
int dep[maxl],fa[maxl];
vector<int> a[maxl],tmp;
typedef pair<int,int> p;
bool vis[maxl];
char s[10];

inline p qry()
{
	int len=tmp.size();
	printf("? %d",len);
	for(int i=0;i<len;i++)
		printf(" %d",tmp[i]);
	puts("");
	fflush(stdout);
	p ret;
	scanf("%d%d",&ret.fir,&ret.sec);
	return ret;
}

inline void dfs(int u)
{
	vis[u]=true;a[dep[u]].push_back(u);
	for(int v:e[u])
	{
		if(vis[v]) continue;
		dep[v]=dep[u]+1;
		fa[v]=u;dfs(v);
	}
}

inline void prework()
{
	scanf("%d",&n);
	for(int i=0;i<=n;i++)
		e[i].clear(),a[i].clear(),vis[i]=false;
	int u,v;
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	tmp.clear();
	for(int i=1;i<=n;i++)
		tmp.push_back(i);
	p ret=qry();
	rt=ret.fir;sumdis=ret.sec;
	dep[rt]=0;fa[rt]=0;
	dfs(rt);
}

inline void mainwork()
{
	int ans=0,l=sumdis/2,r=0,mid;
	p ret;
	for(int i=1;i<=n;i++)
		r=max(r,dep[i]);
	r=min(sumdis,r);
	while(l<=r)
	{
		mid=(l+r)>>1;
		tmp.clear();
		for(int v:a[mid])
			tmp.push_back(v);
		ret=qry();
		if(ret.sec==sumdis)
			l=mid+1,ans=mid,ans1=ret.fir;
		else
			r=mid-1;
	}
	int out=ans1;
	while(dep[out]>sumdis-ans)
		out=fa[out];
	tmp.clear();
	for(int v:a[sumdis-ans])
	if(v!=out)
		tmp.push_back(v);
	if(!tmp.empty())
	{
		ret=qry();
		ans2=ret.fir;
	}
	else
		ans2=rt;
}

inline void print()
{
	printf("! %d %d\n",ans1,ans2);
	fflush(stdout);
	scanf("%s",s);
}

int main()
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。Gym是Codeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.youkuaiyun.com/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.youkuaiyun.com/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.youkuaiyun.com/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值