hdu 3094 树的删边游戏

A tree game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 383    Accepted Submission(s): 180

Problem Description
Alice and Bob want to play an interesting game on a tree. Given is a tree on N vertices, The vertices are numbered from 1 to N. vertex 1 represents the root. There are N-1 edges. Players alternate in making moves, Alice moves first. A move consists of two steps. In the first step the player selects an edge and removes it from the tree. In the second step he/she removes all the edges that are no longer connected to the root. The player who has no edge to remove loses. You may assume that both Alice and Bob play optimally.
 
Input
The first line of the input file contains an integer T (T<=100) specifying the number of test cases. Each test case begins with a line containing an integer N (1<=N<=10^5), the number of vertices,The following N-1 lines each contain two integers I , J, which means I is connected with J. You can assume that there are no loops in the tree.
 
Output
For each case, output a single line containing the name of the player who will win the game.
 
Sample Input
3
3
1 2
2 3
3
1 2
1 3
10
6 2
4 3
8 4
9 5
8 6
2 7
5 8
1 9
6 10
 
Sample Output
Alice
Bob
Alice
 
树的删边游戏网上找的资料

一、链的删边游戏

    游戏规则:对于一条链,两人轮流删边,脱离根的部分byebye,没边可删的人,输。

    这个,应该很简单。那么,它的sg究竟怎么回事捏?

    当只有一个根存在时,先手必败。

    

    当有2个结点时,如图:

    

    所以,红点的sg=1。

    当有3个结点时,如图:

    

    所以,红点的sg=2。

    依次类推。

    链表的sg就这么简单。
    二、树的删边游戏

    游戏规则:对于一棵树,两人轮流删边,脱离根的部分byebye,没边可删的人,输。

    有了链后,我们看树,其实,就是一个组合游戏。

        

    于是乎,很明显,这成了一个Nim游戏的组合。

    所以,在树中,叶子结点的sg=0,其他节点的sg等于儿子结点的sg+1的异或和。

 

    三、局部连通图的删边游戏

    游戏规则:在一个局部连通图上,两人轮流删边,脱离根的部分byebye,没边可删的人,输。局部连通图的构图规则是,在一棵基础树上加边得到,所有形成的环保证不共用边,且只与基础树有一个公共点。

    如图,是一个局部连通图:

    

    因为这些环都是单独悬浮在一棵树上的某些点的。我们单独考虑环。

    对于一个独立的偶环而言,根在偶环上,一定有先手必败。

    原因是,先手删去偶环上的仪表边后,根有了两条链,链的长度一定为一奇一偶,既长短不一,后手只需要把长的那条链转移成合短的那条链长度一样即可。这样,先手必输,根的sg=0。

    对于一个独立的奇环而言,根在奇环上,一定有先手必胜,根的sg=1。

    原因是,先手删去某条边后,可以保证根结点连接的两条链的长度一样长。这样,先手必胜。

    现在把环带进局部连通图中,那些环上的红点就相当于环的根。对于整个图,我们只需要无视所有偶环,把奇环换成一条边。

    如上面的图,按照这个规则变后,就是:

    

    这个时候,又转成了树的删边游戏。

用vector二维容器存储两两顶点之间的关系递归深搜

代码:

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
vector<int> v[100005];
int
sg[100005];
bool
vis[100005];
int
mex(int n)
{

    int
i;
    if
(sg[n]!=-1)
        return
sg[n];
    sg[n]=0;
    vis[n]=true;
    for
(i=0;i<v[n].size();i++)
        if
(!vis[v[n][i]])
            sg[n]^=(mex(v[n][i])+1);
    vis[n]=false;
    return
sg[n];
}

int
main()
{

    int
t,a,b,i,n;
    cin>>t;
    memset(vis,false,sizeof(vis));
    while
(t-- && scanf("%d",&n))
    {

        memset(sg,-1,sizeof(sg));   
        for
(i=1;i<=n;i++)
            v[i].clear();
        for
(i=1;i<n;i++)
        {

            scanf("%d %d",&a,&b);
            v[a].push_back(b);
            v[b].push_back(a);
        }

        if
(mex(1))
            printf("Alice\n");
        else

            printf("Bob\n");
    }

    return
0;
}

posted on 2013-05-26 21:33  雄..  阅读(398)  评论(0)    收藏  举报

导航