1005: [HNOI2008]明明的烦恼
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3484 Solved: 1383
[ Submit][ Status][ Discuss]
Description
自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
Input
第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
Output
一个整数,表示不同的满足要求的树的个数,无解输出0
Sample Input
3
1
-1
-1
1
-1
-1
Sample Output
2
HINT
两棵树分别为1-2-3;1-3-2
题解:
Purfer Sequence
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<cstdlib>
#include<cmath>
#include<fstream>
using namespace std;
int n,m=0,tot=0,fenmu[1005]={0},fenzi[1005]={0},prime[1005]={0};
int ans[10005]={0};
void Fenjie(int zz,int a[]){
int sum;
for(int i=2;i<=zz;++i)
if(prime[i]){
sum=i;
while(sum<=zz){a[i]+=zz/sum;sum*=i;}//神奇
}
return ;
}
void Buildprime(){
int i,j;
for(i=2;i<=1000;++i){
for(j=2;j<=sqrt(i);++j)
if(i%j==0) break;
if(j>sqrt(i)) prime[i]=1;
}
}
int main(){
cin>>n;
Buildprime();
for(int i=1;i<=n;++i){
int d;
cin>>d;
if(d==-1) {m++;continue;}
if(d>1) Fenjie(d-1,fenmu);
tot+=d-1;
}
Fenjie(n-2-tot,fenmu);
Fenjie(n-2,fenzi);
for(int i=1;i<=1000;++i){
fenzi[i]-=fenmu[i];
}
ans[0]=1;
for(int i=1;i<=1000;++i){
while(fenzi[i]>0){
fenzi[i]--;
for(int j=0;j<=10000;++j)
ans[j]*=i;
for(int j=0;j<=10000;++j){
if(ans[j]>9){
ans[j+1]+=ans[j]/10;ans[j]%=10;
}
}
}
}
if(m>0){
for(int i=1;i<=n-2-tot;++i){
for(int j=0;j<=10000;++j)
ans[j]*=m;
for(int j=0;j<=10000;++j){
if(ans[j]>9){
ans[j+1]+=ans[j]/10;
ans[j]%=10;
}
}
}
}
if(tot>n-2||(tot<n-2&&m==0)) {
cout<<0<<endl;return 0;
}
int i=10000;
while(ans[i]==0) i--;
while(i>=0) cout<<ans[i--];
cout<<endl;
return 0;
}

本文介绍了HNOI2008竞赛题目“明明的烦恼”的解决方案,该问题涉及根据指定顶点度数构造不同类型的树,并利用Purfer序列进行计数。通过质因数分解等算法实现。
424

被折叠的 条评论
为什么被折叠?



