CF1363C Game On Leaves(简单博弈)

CF1363C Game On Leaves

题意:

给定 n n n 个节点的无根树。

两名选手轮流操作,每次可以选择一个叶节点并删除它以及所有和它相连的边。叶节点指度数不超过 1 1 1 的节点。删除节点 x x x 的选手胜利。

你需要判断先手是否有必胜策略。具体来讲,如果先手有必胜策略,输出 A y u s h Ayush Ayush,否则输出 A s h i s h Ashish Ashish

多组数据,数据组数 t ≤ 10 t \leq 10 t10 n ≤ 1000 n \leq 1000 n1000

思路:

分类讨论:

  • x x x是叶子节点,则先手赢。
  • n = 1 n=1 n=1,则先手赢。
  • n − 3 n-3 n3是偶数,则先手输。
  • n − 3 n-3 n3是奇数,则先手赢。

关于后面两个讨论的简单证明:

易得知,此时 x x x不是叶子,选 x x x为树根重构这棵树。
CF1363C Game On Leaves(简单博弈)_第1张图片
按规则,考虑把所有叶子节点不断删除,直到 x x x的每个子树只剩一个节点时,如下。
CF1363C Game On Leaves(简单博弈)_第2张图片
由图可观察到,还可以继续删除 x x x的儿子节点。

于是不难想到,以 x x x为根的游戏的最终状态一定以 x x x只有两个儿子节点的形式呈现,因为其他点在不同的时间点都会做为叶子节点删去。
最终状态:
CF1363C Game On Leaves(简单博弈)_第3张图片
所以 n − 3 n-3 n3即表示删去的点数。

  • n − 3 n-3 n3是偶数,则到最终状态时,轮到先手取叶子,取完后另一个人取 x x x,则为后手获胜。
  • n − 3 n-3 n3是奇数,则到最终状态时,轮到后手取叶子,取完后另一个人取 x x x,则为先手获胜。

证毕

Code:

#include
using namespace std;
int d[3000];
/**
 * 简单博弈
 * @return [description]
 */
int main(){
	int n,x;
	int t;
	cin>>t;
	while(t--){
		cin>>n>>x;
		int l,r;
		for(int i=1;i<=n-1;++i)d[i]=0;
		for(int i=1;i<=n-1;++i){
			cin>>l>>r;
			d[l]++;
			d[r]++;
		}
		if(n==1){
			puts("Ayush");

		}
		else if(d[x]==1){
			puts("Ayush");
		}
		else if((n-3)%2==0){
			puts("Ashish");
		}
		else puts("Ayush");
	}
	return 0;
}

你可能感兴趣的:(CF随笔)