牛客算法周周练16 C-树链博弈

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/107560553
今日推荐