TopCoder SRM 570 Div2 1000 CentaurCompanyDiv2

这次的1000算简单的,就是统计有几个子树。
树形DP一波, f [ i ] 表示以 i 为根的子树数量,枚举儿子,转移有三种种情况:

  • 只连之前的儿子( 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;
}

猜你喜欢

转载自blog.csdn.net/ymzqwq/article/details/81660316