题目链接:https://ac.nowcoder.com/acm/contest/6441/C
题意:给一棵n个点的树,1是根节点,每个结点要么黑色要么白色,现在小Bo和小Biao进行博弈,两个人轮流操作,每次选中一个黑点然后可以选择这个结点的任意个祖先将其翻转(白变黑,黑变白),不能操作的人输。给定初始界面,问先手必胜还是后手必胜。
样例:
hint:现选中一个黑色的结点然后对其祖先进行反转操作,但是接着可以在其祖先当中选择第一个黑色结点,进行第二次反转,使得在这个祖先之上的所有祖先恢复原来的状态。因此这里不予考虑,但是需要考虑的是每层的黑色点数,因为层与层之间无法影响,当某层黑色节点数为奇数,则先手必胜,如果每层黑色节点数都是偶数,那么后手必胜。这里使用bfs跑出每层的节点数。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int dep[1234],sum[1234];
int color[1234];
vector<int>v[1234];
int maxd=1;
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&color[i]);
}
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
}
queue<int>q;
q.push(1);
dep[1]=1;
while(q.size()){
int t=q.front();q.pop();
if(color[t])sum[dep[t]]++;
for(auto i:v[t]){
dep[i]=dep[t]+1;
maxd=max(maxd,dep[i]);
q.push(i);
}
}
int flag=0;
for(int i=1;i<=maxd;i++){
if(sum[i]&1)flag=1;
if(flag)break;
}
if(flag)printf("First\n");
else printf("Second\n");
system("pause");
return 0;
}