Tree Tag(博弈,贪心,树的直径)

https://codeforces.com/contest/1405/problem/D

题意:在一棵顶点为n的树上,Alice和Bob开始位于两个不同的顶点,轮流移动,Alice先手。移动时允许停留在同一个顶点上,如果无限步内Alice和Bob占据了同一个顶点,Alice胜,否则Bob胜,求胜者。

思路:考虑YES/NO的单方面。

考虑YES。根据样例,如果Alice能第一步抓到Bob,直接win。所以判Alice和Bob的dis是否<=da。直接用向上标记法求也可以,不必lca。

然后看到第二个链子,想到如果在树的直径的中点,Alice的跨越距离能到树直径两端,那么整个树都能被抓到,Alice必赢。判一个fardis<=da*2。

然后第三个有一点难想。    比如Bob在Alice的da*2的多一个点上,这时候Bob想要逃出去肯定要能每次跳出这个范围,跳出的条件是db>da*2。所以第三个条件是da*2>=db,Alicewin。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug(a) cout<<#a<<"="<g[maxn];
LL n,a,b,da,db;
LL dis=0,fardis=0,farnode=0;
void init()
{
	for(LL i=0;i<=n+10;i++) vis[i]=0;
	dis=0;fardis=0;farnode=0;
}
void dfs1(LL u,LL fa,LL end,LL step)//求a和b的距离
{
	vis[u]=1;
	if(u==end)
	{
		dis=step;
		return;
	}
	for(LL i=0;ifardis){
		fardis=step;
		farnode=u;
	}
}
void solve()
{
	cin>>n>>a>>b>>da>>db;init();
	for(LL i=0;i<=n+10;i++) g[i].clear();
	for(LL i=1;i>x>>y;
		g[x].push_back(y);
		g[y].push_back(x);
	}	
	dfs1(a,-1,b,0);//条件一
	if(dis<=da){
		cout<<"Alice"<>t;
  while(t--)
  {
	solve();
  }
return 0;
}

 

你可能感兴趣的:(贪心,思维,树的dfs)