1. 程式人生 > >牛客國慶集訓派對Day4 H-樹鏈博弈

牛客國慶集訓派對Day4 H-樹鏈博弈

玄學之門

題目:

傳送門

分析:

先上一波核心思想:當每層的黑點個數為偶數時,則先手必敗,反之先手必勝 證明: 1.1.當每層的黑點個數為00時,先手必敗 2.2.若當前狀態為先手必敗,則一定可以通過一步變為先手必勝;若當前狀態為先手必勝,則一定可以通過一步變為先手必敗 所以結論成立 證畢 然後我們跑一遍dfsdfs求出所有層上的黑點個數就可以了

程式碼:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>  
#include
<cstdlib>
#include<algorithm> #include<set> #include<queue> #include<vector> #include<map> #include<list> #include<ctime> #include<iomanip> #include<string> #include<bitset> #include<deque> #include<set> #define LL long long
#define h happy #define ch cheap using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } int x[1005],sum[1005]; vector<int> v[1005]; void dfs(int
a,int f,int d) { if(x[a]) sum[d]++; for(int i=0;i<v[a].size();i++) if(v[a][i]!=f) dfs(v[a][i],a,d+1); return; } int main() { int n=read(); for(int i=1;i<=n;i++) x[i]=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); v[x].push_back(y); v[y].push_back(x); } dfs(1,-1,0); for(int i=0;i<=1000;i++) if(sum[i]&1) {printf("First");return 0;} printf("Second"); return 0; }