CodeForces 1363C :Game On Leaves 树上博弈

传送门

题意

给你一棵树,标记一个点 x x x,每次可以删去一个叶子结点和他所连的边,判断先手赢还是后手赢

分析

想一下特殊情况
n = 1 n = 1 n=1的情况下,先手赢
x x x是叶子结点的情况下,先手赢
剩下的情况,我们可以把这棵树看成以 x x x为根节点的一棵树,然后最后的情况一定是保留下来 x x x和与 x x x链接的两个节点,最后删去一个子节点,就可以直接删去 x x x节点

代码

#pragma GCC optimize(3)
#include 
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
const ll mod = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a) {
	char c = getchar(); T x = 0, f = 1; while (!isdigit(c)) {if (c == '-')f = -1; c = getchar();}
	while (isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();} a = f * x;
}
int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;}
int h[N], e[N], ne[N], idx;
bool st[N];
int d[N];
int n, k;

void add(int x, int y) {
	ne[idx] = h[x], e[idx] = y, h[x] = idx++;
}

void dfs(int u,int fa){
	bool flag = true;
	for(int i = h[u];~i;i = ne[i]){
		int j = e[i];
		if(j == fa) continue;
		flag = false;
	}
	if(!flag) st[u] = true;
}

int main() {
	int T;
	read(T);
	while (T--) {
		memset(h, -1, sizeof h);
		memset(st, 0, sizeof st);
		memset(d, 0, sizeof d);
		idx = 0;
		read(n), read(k);
		for (int i = 1; i < n; i++) {
			int x, y;
			read(x), read(y);
			d[x]++,d[y]++;
		}
		if(n == 1){
			puts("Ayush");
			continue;
		}
		if(d[k] == 1){
			puts("Ayush");
			continue;
		}
		if((n - 3) & 1) puts("Ayush");
		else puts("Ashish");
	}
	return 0;
}

你可能感兴趣的:(大学ACM)