牛客国庆集训派对Day4 H-树链博弈

版权声明:喜欢请点个大拇指,感谢各位dalao。弱弱说下,转载要出处呦 https://blog.csdn.net/qq_35786326/article/details/82945090


题目:

传送门


分析:

先上一波核心思想:当每层的黑点个数为偶数时,则先手必败,反之先手必胜
证明:
1. 1. 当每层的黑点个数为 0 0 时,先手必败
2. 2. 若当前状态为先手必败,则一定可以通过一步变为先手必胜;若当前状态为先手必胜,则一定可以通过一步变为先手必败
所以结论成立
证毕
然后我们跑一遍 d f s dfs 求出所有层上的黑点个数就可以了


代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>  
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define h happy
#define ch cheap
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int x[1005],sum[1005];
vector<int> v[1005];
void dfs(int a,int f,int d)
{
    if(x[a]) sum[d]++;
    for(int i=0;i<v[a].size();i++)
        if(v[a][i]!=f) dfs(v[a][i],a,d+1);
    return;
}
int main()
{
    int n=read();
    for(int i=1;i<=n;i++) x[i]=read();
    for(int i=1;i<n;i++)
    {
        int x=read(),y=read();
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,-1,0);
    for(int i=0;i<=1000;i++) if(sum[i]&1) {printf("First");return 0;}
    printf("Second");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/82945090