本文主要是介绍HDU 3904 A tree game题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【题意】:
给定一个以1号节点为根的含N个节点的树,Alice先手,Bob后手玩一个游戏:轮流删去树中的边,之后将与根断开了联系的部分去除。无法继续删边者为负。
【分析】:
这是树的删边博弈游戏,首先先考虑更加简单的链的删边博弈游戏。
链的删边博弈游戏游戏规则:对于一条链,两人轮流删边,脱离根的部分去除,没边可删的人即输。考虑其sg值。
于是乎,很明显,这成了一个Nim游戏的组合。
(上述资料原版来自:【博弈】无向图删边游戏)
【代码】:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 200001
#define MAXN 100001
struct TREENODE{int f,t,next;}a[MAX];
int DATA,N,last[MAXN],tot;
bool vis[MAXN];
void add(int from,int to)
{a[++tot].t=to;a[tot].next=last[from];last[from]=tot;a[++tot].t=from;a[tot].next=last[to];last[to]=tot;
}
int work(int now)
{int ans=0;for(int i=last[now];i;i=a[i].next){int to=a[i].t;if(!vis[to]){vis[to]=true;ans^=(work(to)+1);}}return ans;
}
int main()
{scanf("%d",&DATA);for(int data=1;data<=DATA;data++){tot=0;memset(last,0,sizeof(last));memset(vis,false,sizeof(vis));scanf("%d",&N);for(int i=1;i<N;i++){int F,T;scanf("%d%d",&F,&T);add(F,T);}vis[1]=true;if(!work(1)) printf("Bob\n");else printf("Alice\n");}return 0;
}
这篇关于HDU 3904 A tree game题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!