CodeForces 23E Tree
树形DP+高精度。
dp[i][j]表示i这个节点所在连通块有j个点。
可以选择和一些儿子相连,也可以完全断开,每种情况保留最大值就可以了。
import java.io.BufferedInputStream; import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger dp[][] = new BigInteger[800][800]; static int tot[]=new int[800]; static int G[][] = new int[800][800]; static int flag[]=new int[800]; static int n; static BigInteger MAX(BigInteger A,BigInteger B) { if( A.compareTo(B) >= 0 ) return A; return B; } static void dfs(int now) { flag[now] = 1; tot[now] = 1; int fail = 1; for (int i = 1; i <= G[now][0]; i++) { if (flag[G[now][i]]==0) { dfs(G[now][i]); fail = 0; BigInteger tmp[]=new BigInteger[800]; for (int j = 1; j <= tot[now]+tot[G[now][i]]; j++) tmp[j] = BigInteger.valueOf(1); for (int j = 1; j <= tot[G[now][i]]; j++) { for (int k = 1; k <= tot[now]; k++) { BigInteger jj =BigInteger.valueOf(j); BigInteger kk =BigInteger.valueOf(k); BigInteger F1=dp[G[now][i]][j].divide(jj); BigInteger F2=dp[now][k].divide(kk); BigInteger F3=jj.add(kk); tmp[j + k] = MAX(tmp[j + k], (F1.multiply(F2)).multiply(F3)); } for (int k = 1; k <= tot[now]; k++) tmp[k] = MAX(tmp[k], dp[G[now][i]][j].multiply(dp[now][k])); } for (int j = 1; j <= tot[G[now][i]]; j++) tmp[1] = MAX(tmp[1], dp[G[now][i]][j]); tot[now] = tot[now] + tot[G[now][i]]; for (int j = 1; j <= tot[now]; j++) dp[now][j] = MAX(dp[now][j], tmp[j]); } } if (fail==1) { tot[now] = 1; dp[now][1] = BigInteger.valueOf(1); } } public static void main(String[] args) { Scanner sc = new Scanner (new BufferedInputStream(System.in)); n = sc.nextInt(); for(int i=1;i<=n;i++) tot[i]=0; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) dp[i][j] =BigInteger.valueOf(1); for(int i=1;i<=n;i++) G[i][0]=0; for(int i=1;i<=n;i++) flag[i]=0; for (int i = 1; i < n; i++) { int u=sc.nextInt(); int v=sc.nextInt(); G[u][0]++; G[u][G[u][0]]=v; G[v][0]++; G[v][G[v][0]]=u; } dfs(1); BigInteger ans=BigInteger.valueOf(1); for (int i = 1; i <= n; i++) ans = MAX(ans, dp[1][i]); System.out.println(ans); } }