失败的代码。。。不过思路是对的
/* 树的 prufer数列 一棵树有唯一的prufer数列 长度为 节点n-2 一个prufer数列 有唯一的一棵树 大小为 长度 l+2 优质博客: https://blog.csdn.net/sleepiest/article/details/81558924 对于确定的和不确定的分别求解 然后乘法原理 确定的 首先判断能否成树 根据prefer数列原理? sigma(di-1)不能超过 n-2 然后就是博客里面的组合数+乘法原理 不确定的 prufer数列还剩下 k=n-2-sigma(di-1) 空位 此时可以吧不确定的点任一放进去 有 (不确定节点数)^(剩下空位) 组合方案数 排列公式里面有阶乘 可以质因数分解 约分 算出答案 这里用高精 不过调了很久都没过。。干脆不做了 */ #include<cstdio> #include<cstring> #define ll long long using namespace std; const int N=1050; struct BigInt { int num[10000],len; BigInt() { memset(num,0,sizeof(num)); len=1; } BigInt operator* (const int &rhs) const { BigInt ans; ans.len=len+6; for (int i=1;i<=len;i++) ans.num[i]+=num[i]*rhs; for (int i=1;i<ans.len;i++) if (ans.num[i]>9) { ans.num[i+1]+=ans.num[i]/10; ans.num[i]%=10; } while (!ans.num[--ans.len]) return ans; } BigInt operator/ (const int &rhs) const { BigInt ans=*this; ans.len++; for (int i=ans.len;i;i--) { ans.num[i-1]+=ans.num[i]%rhs*10; ans.num[i]/=rhs; } while (!ans.num[--ans.len]); return ans; } void print() { while (!num[--len]); for(int i=len;i;i--) printf("%d",num[i]);printf("\n"); } }res; int n,d[N],rest,all,top; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&d[top+1]); if(d[top+1]==-1) continue; top++;all+=d[top]-1; if(!d[top]) {puts("0");return 0;} } if(all>2*n-2) {puts("0");return 0;} // 无解 res.num[1]=1; for(int i=n-1-all;i<=n-2;i++) res=res*i; for(int i=1;i<=n-2-all;i++) res=res*(n-top); for(int i=1;i<=top;i++) { for(int j=2;j<=d[i]-1;j++) res=res/j; } res.print(); return 0; }

京公网安备 11010502036488号