/* *State: 3094 156MS 2144K 1315 B C++ *题目大意: * 给定n棵树(树中包括简单的多边形),每棵树有m个结点(1~m)和k条边 * (结点1给根节点)。Harry和Sally轮流删除树上的一条边,并切移除所 * 以和根节点不再连通的所有边和结点。最后不能再删除边的一方为输。 *解题思路: * 叶子节点的 SG 值为 0;中间节点的 SG 值为它的所有子节点的 SG 值 * 加 1 后的异或和。(加1是因为拆成链的时候,要考虑到链头结点,因为 * 算的其实就是链头的结点。) *解题感想: * 略。 */
View Code
#include <iostream> #include <vector> using namespace std; const int MAX = 100005; int sg[MAX], cnt, head[MAX]; bool vst[MAX]; typedef struct node_ { int v; int next; }N; N edge[2 * MAX]; void addEdge(int u, int v) { edge[cnt].v = v; edge[cnt].next = head[u]; head[u] = cnt++; edge[cnt].v = u; edge[cnt].next = head[v]; head[v] = cnt++; } int dfs(int n) { vst[n] = true; if(sg[n] != -1) return sg[n]; if(head[n] == -1) return sg[n] = 0; vector<int> sg_son; for(int f = head[n]; f != -1; f = edge[f].next) { int son = edge[f].v; if(vst[son] == false) sg_son.push_back(dfs(son)); } int yihuo = 0; for(unsigned i = 0; i < sg_son.size(); i++) { yihuo ^= sg_son[i] + 1; } return sg[n] = yihuo; } void init() { cnt = 0; memset(head, -1, sizeof(head)); memset(sg, -1, sizeof(sg)); memset(vst, false, sizeof(vst)); } int main(void) { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int cas; scanf("%d", &cas); while(cas--) { init(); int n; scanf("%d", &n); for(int i = 0; i < n - 1; i++) { int u, v; scanf("%d %d", &u, &v); addEdge(u, v); addEdge(v, u); } int flag = dfs(1); if(!flag) printf("Bob\n"); else printf("Alice\n"); } return 0; }