[AGC017D] Game on Tree
阿新 • • 發佈:2021-12-23
顯然是水部落格。
前言
關於萌新剛學會SG函式而只會 \(O(n^2)\) 做法這件事。
題目
講解
從易到難思考。
如果根節點只有一個兒子,這很好,先手砍掉這個點就能獲勝。
如果根節點有兩個兒子,那麼率先到一個兒子狀態的人獲勝。然後遞迴看這兩個兒子的遊戲狀態。
此時就已經可以用SG函式分析了,但顯然萌新不太會證明,只會感性理解每個點的SG值為其所有兒子SG值+1的異或和。
因此只需要簡單的dfs就可以完成這道題。
時間複雜度 \(O(n)\)。
程式碼
//12252024832524 #include <bits/stdc++.h> #define TT template<typename T> using namespace std; typedef long long LL; const int MAXN = 100005; int n; LL Read() { LL x = 0,f = 1; char c = getchar(); while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();} return x * f; } TT void Put1(T x) { if(x > 9) Put1(x/10); putchar(x%10^48); } TT void Put(T x,char c = -1) { if(x < 0) putchar('-'),x = -x; Put1(x); if(c >= 0) putchar(c); } TT T Max(T x,T y){return x > y ? x : y;} TT T Min(T x,T y){return x < y ? x : y;} TT T Abs(T x){return x < 0 ? -x : x;} int head[MAXN],tot; struct edge { int v,nxt; }e[MAXN<<1]; void Add_Edge(int x,int y) { e[++tot] = edge{y,head[x]}; head[x] = tot; } void Add_Double_Edge(int x,int y) { Add_Edge(x,y); Add_Edge(y,x); } int dfs(int x,int fa) { int ret = 0; for(int i = head[x]; i ;i = e[i].nxt) if(e[i].v ^ fa) ret ^= dfs(e[i].v,x)+1; return ret; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); n = Read(); for(int i = 1;i < n;++ i) Add_Double_Edge(Read(),Read()); printf(dfs(1,0) ? "Alice\n" : "Bob\n"); return 0; }