hdu -- 6105 -- Gameia(博弈)

来源:互联网 发布:网络延时一般多少 编辑:程序博客网 时间:2024/06/04 17:58

Gameia

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1006 Accepted Submission(s): 428

Problem Description
Alice and Bob are playing a game called ‘Gameia ? Gameia !’. The game goes like this :
0. There is a tree with all node unpainted initial.
1. Because Bob is the VIP player, so Bob has K chances to make a small change on the tree any time during the game if he wants, whether before or after Alice’s action. These chances can be used together or separate, changes will happen in a flash. each change is defined as cut an edge on the tree.
2. Then the game starts, Alice and Bob take turns to paint an unpainted node, Alice go first, and then Bob.
3. In Alice’s move, she can paint an unpainted node into white color.
4. In Bob’s move, he can paint an unpainted node into black color, and what’s more, all the other nodes which connects with the node directly will be painted or repainted into black color too, even if they are white color before.
5. When anybody can’t make a move, the game stop, with all nodes painted of course. If they can find a node with white color, Alice win the game, otherwise Bob.
Given the tree initial, who will win the game if both players play optimally?

Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with two integers N and K : the size of the tree and the max small changes that Bob can make.
The next line gives the information of the tree, nodes are marked from 1 to N, node 1 is the root, so the line contains N-1 numbers, the i-th of them give the farther node of the node i+1.

Limits
T≤100
1≤N≤500
0≤K≤500
1≤Pi≤i

Output
For each test case output one line denotes the answer.
If Alice can win, output “Alice” , otherwise “Bob”.

Sample Input
2
2 1
1
3 1
1 2

Sample Output
Bob
Alice

Source
2017 Multi-University Training Contest - Team 6

题意:给你一颗有 n 个节点的树,Alice 和 Bob 两人轮流把节点染色,Alice 先行动。当 Alice 行动时,Alice把未染色的点染上白色。当 Bob 行动时,Bob 把未染色的点染上黑色,同时与当前染色的这个点直接相连的所有点都会变成黑色,不管之前这些点是未被染色还是白色,都会变为黑色。因为 Bob 是VIP,所以 Bob 有可以切断 0 ~ k 条边的权利。当没有点可以染色时,若所有点都为黑色,则 Bob 赢,否则 Alice 赢。

解题思路:
一.若以任意一个点为根节点时,树中有图1中的结构,则 Alice 赢(至于为什么,可以自己推推)。

图1
这里写图片描述

例如

图2
这里写图片描述

二.若 n 为奇数时 Alice 赢。

三.若切 m (m <= k) 刀不可以把树分成 以图3中的结构(两个节点为一组)为单位的图,则 Alice 赢。

图3
这里写图片描述

例如:

  • 如果不切的话,
    ① Alice 染节点4。
    ② Bob 只能染节点3(因为这是最优的染法) ,这时节点2,3,4都为黑色。
    ③ Alice 染节点1。
    游戏结束,节点1为白色,Alice 赢。

  • 如果切的话,Bob赢。

图4
这里写图片描述

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;typedef long long LL;const int maxn = 2e3 + 5;int last[maxn],pre[maxn],other[maxn],d[maxn];int all;void build(int x,int y){    pre[++all] = last[x];    last[x] = all;    other[all] = y;}bool dfs(int x,int fa){    int ans = 0;    int dt = last[x];    while(dt != -1){        int dr = other[dt];        if(dr != fa){            if(d[dr] == 1) ans++;        }        dt = pre[dt];    }    if(ans >= 2) return true;    return false;}int main(){    int t;    scanf("%d",&t);    while(t--){        all = -1;        memset(last,-1,sizeof(last));        memset(d,0,sizeof(d));        int n,k;        scanf("%d %d",&n,&k);        for(int i = 1;i <= n - 1;i++){            int x;            scanf("%d",&x);            build(x,i + 1);            build(i + 1,x);            d[x]++;            d[i + 1]++;        }        int flag = 0;        for(int i = 1;i <= n;i++){            if(dfs(i,0)){                flag = 1;                break;            }        }        if(flag == 1 || n % 2 == 1 || k < n / 2 - 1) printf("Alice\n");        else printf("Bob\n");    }    return 0;}