#include using namespace std; typedef long long ll; #define inf 10e17 #define rep(i,n) for(long long i=0; i()) #define debug(x) std::cerr << (x) << std::endl; #define roll(x) for (auto&& itr : x) { cerr << (itr) << " "; } template inline void chmax(T &ans, T t) { if (t > ans) ans = t;} template inline void chmin(T &ans, T t) { if (t < ans) ans = t;} /* Union-Find-Tree */ /* 必ず要素数をコンストラクタに入れること */ template class Union_Find { using size_type = std::size_t; using _Tp = T; public: vector<_Tp> par; vector<_Tp> rnk; // 親の根を返す。値の変更は認めない。 const _Tp & operator[] (size_type child) { find(child); return par[child]; } Union_Find (size_type n) { par.resize(n), rnk.resize(n); for (int i = 0; i < n; ++i) { par[i] = i; rnk[i] = 0; } } // 木の根を求める _Tp find(_Tp x) { if (par[x] == x) return x; else return par[x] = find(par[x]); } // xとyの属する集合を併合 void merge(_Tp x, _Tp y) { x = find(x); y = find(y); if (x == y) return; if (rnk[x] < rnk[y]) { par[x] = y; } else { par[y] = x; if (rnk[x] == rnk[y]) rnk[x]++; } } // xとyが同じ集合に属するか否か bool same(_Tp x, _Tp y) { return find(x) == find(y); } }; int main() { ll n; cin >> n; Union_Find uf(n); map mp; rep(i, n-1) { int u, v; cin >> u >> v; uf.merge(u, v); mp[u] += 1; mp[v] += 1; } int root = uf.find(0); set st; st.insert(root); rep(i, n) { if (uf.find(i) != root) { st.insert(uf.find(i)); } } if (st.size() > 2) { cout << "Alice" << endl; } else { if (st.size() == 1) { cout << "Bob\n"; } else { rep(i, n) { if (mp[i] == 1) { cout << "Alice" << endl; return 0; } } cout << "Bob" << endl; } } }