Before the Beginning
转载请将本段放在文章开头显眼处,如有二次创作请标明。
原文链接:https://www.codein.icu/nowcoderweekly16/
每层黑色节点数都为偶数时,先手必败。
假设先手选择一个黑点,不翻转祖先,则后手选择同层黑点,不翻转祖先,状态不变。
假设先手翻转祖先,则后手翻转对应层的祖先,状态不变。
这样逐层消去,末状态为与根节点相连的黑点为偶数个,此时翻转祖先不改变结果,依次取黑,后手胜。
否则,若有一层为奇数,则先手可以一步将所有层设为偶数,随后将后手代入上述推导,便是先手胜局。
#include <cstdio> #include <algorithm> #include <ctype.h> const int bufSize = 1e6; inline char nc() { #ifdef DEBUG return getchar(); #endif static char buf[bufSize], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, bufSize, stdin), p1 == p2) ? EOF : *p1++; } inline void read(char *s) { static char c; for (; !isalpha(c); c = nc()); for (; isalpha(c); c = nc()) *s++ = c; *s = '\0'; } template<typename T> inline T read(T &r) { static char c; static int flag; flag = 1, r = 0; for (c = nc(); !isdigit(c); c = nc()) if (c == '-') flag = -1; for (; isdigit(c); c = nc()) r = r * 10 + c - 48; return r *= flag; } const int maxn = 1100; const int maxm = maxn * 2; struct node { int to,next; }E[maxm]; int head[maxn]; inline void add(const int &x,const int &y) { static int tot = 0; E[++tot].next = head[x],E[tot].to = y,head[x] = tot; } int n; int col[maxn],dep[maxn]; int cnt[maxn][2]; void dfs(int u,int fa) { dep[u] = dep[fa] + 1; cnt[dep[u]][col[u]]++; for (int p = head[u]; p; p = E[p].next) { int v = E[p].to; if(v == fa) continue; dfs(v,u); } } int main() { read(n); for (int i = 1; i <= n; ++i) read(col[i]); for(int i = 1;i<n;++i) { int a,b; read(a),read(b),add(a,b),add(b,a); } //不加边都能过样例... dfs(1,0); for (int i = 1; i <= n; ++i) if(cnt[i][1] & 1) {puts("First");return 0;} puts("Second"); return 0; }