求条 F1
  • 板块学术版
  • 楼主AfterFullStop
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/9/21 00:36
  • 上次更新2024/9/21 08:31:07
查看原帖
求条 F1
555065
AfterFullStop楼主2024/9/21 00:36

思路大概就是把根到这个点的链拎出来,然后求出每个往下能走最深多少,然后博弈。

#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define ld long double
#define mkp make_pair
using namespace std;
const int maxn=2e5+7;
int n;
vector<int>vec[maxn];
int f[maxn];
int maxd[maxn],sema[maxn];
const int inf=1e9;
void dfs(int u,int fa){
	f[u]=fa;
	maxd[u]=1;sema[u]=-inf;
	for(auto v:vec[u]){
		if(v==fa)continue;
		dfs(v,u);
		if(maxd[v]+1>maxd[u]){
			sema[u]=maxd[u];
			maxd[u]=maxd[v]+1;
		}
		else if(maxd[v]+1>sema[u]){
			sema[u]=maxd[v]+1;
		}
	}
}
int pnt[maxn],tot;
int pnt2[maxn];
int pnt3[maxn];
void solve(){
	cin>>n;
	for(ri i=1;i<=n;i++)vec[i].clear();
	for(ri i=2;i<=n;i++){
		int u,v;cin>>u>>v;
		vec[u].emplace_back(v);vec[v].emplace_back(u);
	}
	dfs(1,0);
	int x;cin>>x>>x;
	int pre=0;
	tot=0;
//	for(ri i=1;i<=n;i++)cout<<maxd[i]<<' ';cout<<endl;
	while(x){
		int val;
		if(maxd[x]==maxd[pre]+1&&pre)val=sema[x];
		else val=maxd[x];
		pnt[++tot]=val;
		pre=x;
		x=f[x];
	}
	reverse(pnt+1,pnt+1+tot);
	for(ri i=1;i<=tot;i++)pnt2[i]=pnt[i]+i-1;
	for(ri i=1;i<=tot;i++)pnt3[i]=pnt[i]+tot-i;
	for(ri i=2;i<=tot;i++)pnt2[i]=max(pnt2[i],pnt2[i-1]);
	for(ri i=tot-1;i;i--)pnt3[i]=max(pnt3[i],pnt3[i+1]);
	int p1=1,p2=tot,o=0;
	while(1){
		if(o==0){
			if(pnt[p1]+p1-1>=pnt3[p1+1]){
				cout<<"Alice\n";
				return;
			}
			else p1++;
			if(p1==p2){
				cout<<"Bob\n";
				return;
			}
		}
		else{
			if(pnt[p2]+tot-p2>=pnt2[p2-1]){
				cout<<"Bob\n";
				return;
			}
			else p2--;
			if(p1==p2){
				cout<<"Alice\n";
				return;
			}
		}
		o^=1;
	}
}
signed main(){
	ios::sync_with_stdio(0);
	int T;cin>>T;
	while(T--)solve();
	return 0;
}
/*
1
3
1 2 3
*/
2024/9/21 00:36
加载中...