这次的1000算简单的,就是统计有几个子树。
树形DP一波,
f[i]
f
[
i
]
表示以
i
i
为根的子树数量,枚举儿子,转移有三种种情况:
- 只连之前的儿子()
- 只连当前儿子( f[v[i]]+1 f [ v [ i ] ] + 1 )
- 都连( f[i]∗(f[v[i]]+1) f [ i ] ∗ ( f [ v [ i ] ] + 1 ) )
分别计数即可。
#include <bits/stdc++.h> #define ll long long using namespace std; const int N=55; const int M=N<<1; int n,cnt; int head[N],Next[M],v[M]; ll f[N]; class CentaurCompanyDiv2 { public: long long count( vector <int> a, vector <int> b ); }; void add(int x,int y){ Next[++cnt]=head[x]; head[x]=cnt; v[cnt]=y; } void dfs(int x,int fa){ for(int i=head[x];i!=-1;i=Next[i]) if (v[i]!=fa){ dfs(v[i],x); f[x]*=(f[v[i]]+2); f[x]+=f[v[i]]+1; } } long long CentaurCompanyDiv2::count(vector <int> a, vector <int> b) { n=a.size()+1;cnt=0; memset(head,-1,sizeof head); for(int i=0;i<n-1;i++) add(a[i],b[i]),add(b[i],a[i]); memset(f,0,sizeof f); dfs(1,0); ll ans=0; for(int i=1;i<=n;i++) ans+=f[i]; return ans+n+1; }