#include #include #include using namespace std; template struct Edge { int from, to; T cost; int idx; Edge() = default; Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {} operator int() const { return to; } }; template struct Graph { vector>> g; int es; Graph() = default; explicit Graph(int n) : g(n), es(0) {} size_t size() const { return g.size(); } void add_directed_edge(int from, int to, T cost = 1) { g[from].emplace_back(from, to, cost, es++); } void add_edge(int from, int to, T cost = 1) { g[from].emplace_back(from, to, cost, es); g[to].emplace_back(to, from, cost, es++); } void read(int M, int padding = -1, bool weighted = false, bool directed = false) { for (int i = 0; i < M; i++) { int a, b; cin >> a >> b; a += padding; b += padding; T c = T(1); if (weighted) cin >> c; if (directed) add_directed_edge(a, b, c); else add_edge(a, b, c); } } }; template using Edges = vector>; template struct LowLink : Graph { public: using Graph::Graph; vector ord, low, articulation; vector> bridge; using Graph::g; virtual void build() { used.assign(g.size(), 0); ord.assign(g.size(), 0); low.assign(g.size(), 0); int k = 0; for (int i = 0; i < (int) g.size(); i++) { if (!used[i]) k = dfs(i, k, -1); } } explicit LowLink(const Graph &g) : Graph(g) {} private: vector used; int dfs(int idx, int k, int par) { used[idx] = true; ord[idx] = k++; low[idx] = ord[idx]; bool is_articulation = false, beet = false; int cnt = 0; for (auto &to : g[idx]) { if (to == par && !exchange(beet, true)) { continue; } if (!used[to]) { ++cnt; k = dfs(to, k, idx); low[idx] = min(low[idx], low[to]); is_articulation |= par >= 0 && low[to] >= ord[idx]; if (ord[idx] < low[to]) bridge.emplace_back(to); } else { low[idx] = min(low[idx], ord[to]); } } is_articulation |= par == -1 && cnt > 1; if (is_articulation) articulation.push_back(idx); return k; } }; int divide = 0; vector visited; void dfs(LowLink<> &g, int v) { for (auto &edge:g.g[v]) { if (!visited[edge.to]) { visited[edge.to] = true; dfs(g, edge.to); } } } int main() { int n; cin >> n; LowLink<> g(n); g.read(n - 1, 0); g.build(); visited.resize(n); for (int i = 0; i < n; i++) { if (!visited[i]) { divide++; visited[i] = true; dfs(g, i); } } if (divide > 2)cout << "Alice" << endl; else if (divide == 2 && g.bridge.size())cout << "Alice" << endl; else cout << "Bob" << endl; return 0; }