【AT2376】Black and White Tree

链接:(被吃了)

解法:树形dp

首先,对于任意一个叶子节点 l 其父亲为 u ,那么选择 u 一定优于选择 l 。选择 u 后,对手必须选择 l ,将这称为一轮操作。
对于一个节点 u ,记 l e a f u 为以 u 为父亲的叶子节点个数,那么显然若 l e a f u > 1 ,则先手必胜。
考虑到将每轮操作的顺序打乱不会影响结果,故可以假设先手在存在叶子节点的情况下优先选择其父亲。每次选择一个节点后,相当于在树种删除该节点并继续执行操作(如下下图),两次dfs递归处理即可。
这里写图片描述

代码

#include<iostream>
#include<cstdio>
#include<vector>

using namespace std;

vector<int> point[100001];
int n,x,y,siz[100001],son[100001];
bool check[100001];

void dfs1(int u,int f){siz[u]=1;for(int v:point[u])if(v!=f)dfs1(v,u),siz[u]+=siz[v];}

void dfs2(int u,int f){
    for(int v:point[u])if(v!=f){dfs2(v,u);if(siz[v]>0)++son[u];}
    if(son[u]==1)siz[u]=0;if(son[u]>1)puts("First"),exit(0);
}

int main(){
    scanf("%d",&n);for(int i=1;i<n;++i)scanf("%d%d",&x,&y),point[x].push_back(y),point[y].push_back(x);
    dfs1(1,0);dfs2(1,0);
    puts(siz[1]?"First":"Second");
}

猜你喜欢

转载自blog.csdn.net/ezoixx174/article/details/81744652