hdu -- 6105 -- Gameia(博弈)

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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值