Gym102392F Game on a Tree(博弈論)
阿新 • • 發佈:2020-11-24
首先我們發現每兩個點會構成一對,他們公用一條邊,且邊集不能共用任何一個點
如果我們可以找到這樣的邊集使得所有點都被選中,那麼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; forView Code(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; }