牛客小白月赛2 F.黑黑白白

牛客小白月赛2 F.黑黑白白

题目链接

题目描述

艮为山,动静得宜,适可而止;兑为泽,刚内柔外,上下相和。
艮卦:兼山,艮;君子以思不出其位。财帛常打心头走,可惜眼前难到手,不如意时且忍耐,逢着闲事休开口。
兑卦:丽泽,兑;君子以朋友讲习。这个卦象真可取,觉着做事不费力,休要错过这机关,事事觉得随心意。

有一个棋子放在一颗有根树的根上。你和算卦先生轮流把这个棋子向所在点的其中一个儿子移动(只能移动到儿子)。不能再移动就算失败(即棋子所在节点没有儿子)。
算卦先生来问你,如果你先手,你是否有必胜策略?

输入描述:

第一行一个数 T,表示有 T 组数据。
接下去每组数据的第一行有两个数 n,r ,表示树有 n 个节点,其中 r 为根节点编号(从 1 开始编号)。
接下去 n - 1 行每行两个数字 u, v ,表示点 u 和 v 之间有一条边。

输出描述:

每组数据输出一行, "Gen" \texttt{"Gen"} "Gen" 表示先手有必胜策略, "Dui" \texttt{"Dui"} "Dui" 表示没有。

示例1

输入

2
3 1
1 2
2 3
5 4
1 2
1 3
3 4
4 5

输出

Dui
Gen

简单的树上博弈,先手如果有 k k k 个选择,当这 k k k 种选择都会使后手获胜,则先手必败,如果有一种情况能使先手获胜,则先手必胜,用 DFS 在树上转移状态即可,AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e4+5;
int t,n,s,u,v,vis[N];
vector<int>G[N];
void init(){
    for(int i=0;i<=n;i++) G[i].clear(),vis[i]=0;
}
bool dfs(int u){
    bool flag=1;
    vis[u]=1;
    for(auto v:G[u]){
        if(!vis[v]&&dfs(v)==1){
            flag=0;
            break;
        }
    }
    return flag;
}

int main()
{
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&s);
        init();
        for(int i=0;i<n-1;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        if(dfs(s)) printf("Dui\n");
        else printf("Gen\n");
    }
}

你可能感兴趣的:(博弈,DFS,牛客)