HDU 6105 Gameia【思维+博弈】

来源:互联网 发布:mac装win7未能启动 编辑:程序博客网 时间:2024/05/16 08:43

题目链接

题意:有一棵树,Alice和Bob往树上没染过色的节点染色,Alice先手。Alice涂白色,Bob涂黑色。当Bob把一个节点涂成黑色的时候,和这个节点直接相邻的节点也都会变成黑色,无论它原来是没有颜色还是已经被涂成白色。Bob还有k次机会,每次可以去掉树上的一条边,这个机会可以在任何时候使用。如果整棵树上没有没有涂色的节点了,游戏结束,此时若树上有白色的节点,Alice赢,否则Bob赢。

可以想象,如果我把这棵树分成很多个两个两个相连的小树,那么Bob一定赢,因为Alice涂一个点,Bob就涂这个子树上的另一个点,Alice那个点就变成黑的了。所以如果点数为奇数,Alice赢,如果为偶数,则如果有一个节点有两个或以上节点数为奇数的子节点,Alice一定赢。因为两个两个分分到中心一定是菊花状的,没法分成两个两个的,此时Alice只要涂中间节点,Bob就输了。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <vector>#include <queue>#include <set>#include <map>using namespace std;#define ll long longconst int maxn=510;int T;int N,K;vector <int> vec[maxn];int degree[maxn];bool vis[maxn];int flag=0;int main(){    scanf("%d",&T);    while (T--){        scanf("%d %d",&N,&K);        for (int i=1;i<=N;i++){            vec[i].clear();        }        int x;        for (int i=2;i<=N;i++){            scanf("%d",&x);            vec[x].push_back(i);        }        flag=0;        for (int i=1;i<=N;i++){            int cnt=0;            if (vec[i].size()%2==1){                cnt++;            }            if (cnt>=2){                flag=1;                break;            }        }        if (N%2==1) printf("Alice\n");        else if (N/2-1>K)   printf("Alice\n");        else if (flag)   printf("Alice\n");        else    printf("Bob\n");    }}


原创粉丝点击