首先我们发现每两个点会构成一对,他们公用一条边,且边集不能共用任何一个点
如果我们可以找到这样的边集使得所有点都被选中,那么bob是必赢的,否则是必输的
原因是,我们对于每个点都能找到一个对应匹配的点,不论alice选什么,bob都有的选,直到alice选不到
那么反之alice必胜,因为alice只要找到一个未匹配点即可。
这里再简单分析一下:
1.假设alice选了一个未匹配点,bob不可能直接选到一个未匹配点,不然就能使他们匹配
2.bob只能选一个匹配点,这样先后手转换,alice总能找到bob选的对应的匹配点,并且因为我们已经是最大匹配了,所以bob不可能找到未匹配点,否则原来的匹配就不是最大的
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,int> pll; const int N=1e6+10; const int inf=0x3f3f3f3f; int h[N],e[N],ne[N],idx; int f[N]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ f[u]=0; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); f[u]+=f[j]; } if(!f[u]) f[u]=1; else{ f[u]--; } } int main(){ ios::sync_with_stdio(false); memset(h,-1,sizeof h); int i; int n; cin>>n; for(i=1;i<n;i++){ int a,b; cin>>a>>b; add(a,b); add(b,a); } dfs(1,-1); if(f[1]==0){ cout<<"Bob"<<endl; } else{ cout<<"Alice"<<endl; } return 0; }