传送门
裸的树形dp。
f[i][0/1]表示当前位置没用/用了
转移暴力就可以了
然后就是喜闻乐见的高精度模板了。
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1005
#define ll long long
#define mo 1000000000
using namespace std;
struct bignum{
ll a[25];
bignum(int x=0){
memset(a,0,sizeof(a));
if (!x) return;
a[1]=x; a[0]=1;
}
friend bignum operator +(bignum a,bignum b){
bignum c;
c.a[0]=max(a.a[0],b.a[0]);
for (int i=1;i<=c.a[0];i++) c.a[i]=a.a[i]+b.a[i];
for (int i=1;i<=c.a[0];i++){
c.a[i+1]+=c.a[i]/mo;
c.a[i]%=mo;
}
if (c.a[c.a[0]+1]) c.a[0]++;
return c;
}
friend bignum operator *(bignum a,bignum b){
bignum c;
for (int i=1;i<=a.a[0];i++){
ll x=0;
for (int j=1;j<=b.a[0];j++){
x+=c.a[i+j-1]+a.a[i]*b.a[j];
c.a[i+j-1]=x%mo;
x/=mo;
}
c.a[i+b.a[0]]=x;
}
c.a[0]=a.a[0]+b.a[0];
while (c.a[0]&&!c.a[c.a[0]]) c.a[0]--;
return c;
}
void print(){
printf("%lld",a[a[0]]);
for (int i=a[0]-1;i>0;i--)
printf("%09lld",a[i]);
puts("");
}
};
vector<int> e[N];
int f[N][2];
bignum g[N][2];
int n,x,y,z;
void dfs(int x,int y){
if (f[x][y]!=-1) return;
f[x][y]=0; g[x][y]=bignum(0);
if (!e[x].size()&&y) return;
if (!y){
g[x][y]=bignum(1);
for (int i=0;i<e[x].size();i++){
dfs(e[x][i],0); dfs(e[x][i],1);
if (f[e[x][i]][0]>f[e[x][i]][1]){
f[x][y]=f[x][y]+f[e[x][i]][0];
g[x][y]=g[x][y]*g[e[x][i]][0];
}
else{
f[x][y]=f[x][y]+f[e[x][i]][1];
if (f[e[x][i]][0]!=f[e[x][i]][1])
g[x][y]=g[x][y]*g[e[x][i]][1];
else g[x][y]=g[x][y]*(g[e[x][i]][0]+g[e[x][i]][1]);
}
}
return;
}
int p; bignum q;
for (int i=0;i<e[x].size();i++)
dfs(e[x][i],0),dfs(e[x][i],1);
for (int i=0;i<e[x].size();i++){
p=0; q=bignum(1);
for (int j=0;j<e[x].size();j++)
if (j!=i){
if (f[e[x][j]][0]>f[e[x][j]][1]){
p=p+f[e[x][j]][0];
q=q*g[e[x][j]][0];
}
else{
p=p+f[e[x][j]][1];
if (f[e[x][j]][0]!=f[e[x][j]][1])
q=q*g[e[x][j]][1];
else q=q*(g[e[x][j]][0]+g[e[x][j]][1]);
}
}
else{
p=p+f[e[x][j]][0]+1;
q=q*g[e[x][j]][0];
}
if (p>f[x][y]){
f[x][y]=p; g[x][y]=bignum(0);
}
if (p==f[x][y])
g[x][y]=g[x][y]+q;
}
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
while (y--){
scanf("%d",&z);
e[x].push_back(z);
}
}
memset(f,-1,sizeof(f));
dfs(1,0);
dfs(1,1);
if (f[1][0]<f[1][1])
f[1][0]=f[1][1],g[1][0]=0;
if (f[1][0]==f[1][1])
g[1][0]=g[1][0]+g[1][1];
printf("%d\n",f[1][0]);
g[1][0].print();
}