明明的烦恼

自从明明学了树的结构,就对奇怪的树产生了兴趣...... 

给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
Input
第一行为N(0 < N < = 1000)
接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
Output
一个整数,表示不同的满足要求的树的个数,无解输出0
Sample Input
3
1
-1
-1
Sample Output
2
HINT
两棵树分别为1-2-3;1-3-2 

input 

8
2
2
-1
-1
-1
-1
-1
-1

output

38880

Sol:
Purfer编码共8-2个位置
发现1的度为2,则出现1次,于是C(6,1)
发现2的度为2,则出现1次,于是C(5,1)
还有4个位置没有放东西,于是放度没有限制的那6个点,有6^4种方式
于是ans=38880

 1 #include<queue>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define fi(i,a,b) for(int i=(a);i<=(b);++i)
 9 #define fj(j,a,b) for(int j=(a);j<=(b);++j)
10 #define maxn 1005
11 #define inf 1000000000
12 using namespace std;
13 inline long long read()
14 {
15     long long x=0,f=1;char ch=getchar();
16     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,cnt,sum;
21 int d[maxn],prime[maxn],c[maxn],t[maxn*20];
22 bool flg,p[maxn];
23 void getprime(int x)
24 {
25     memset(p,1,sizeof(p));
26     prime[0]=1; prime[1]=2;
27     fi(i,2,x)if(p[i]){fj(j,2,x/i)p[i*j]=0;prime[++prime[0]]=i;}
28 }
29 void update(int x,int m)
30 {
31     for(int i=1;i<=prime[0]&&x>1;++i)
32     while(!(x%prime[i]))
33     {
34         x/=prime[i];c[i]+=m;
35     }
36 }
37 int main()
38 {
39 //  freopen("data.in","r",stdin);
40     n=read(); getprime(1000);
41 //  fi(i,1,prime[0])printf("%d\n",prime[i]);
42     fi(i,1,n){
43         d[i]=read();
44         if(!d[i]||d[i]>=n)flg=1;
45         if(d[i]==-1)continue;
46         ++cnt; sum+=d[i]-1;
47         fj(j,2,d[i]-1)update(j,-1);
48     }
49     if(n==1&&d[1]>0){printf("1");return 0;}else if(n==1)flg=1;
50     if(n==2&&!flg){printf("1");return 0;}
51     if(flg){printf("0\n");return 0;}
52     fi(i,2,n-2)update(i,1);
53     fi(i,2,n-2-sum)update(i,-1);
54     update(n-cnt,n-2-sum);
55     t[0]=t[1]=1;
56 //  printf("%d\n",c[1]);
57     fi(i,1,prime[0])while(c[i]){
58         if(c[i]<0){printf("0\n");return 0;}
59 //      printf("%d %d\n",prime[i],c[i]);
60 //      printf("%d\n",prime[i]);
61         --c[i];
62         fj(j,1,t[0])t[j]*=prime[i];
63         fj(j,1,t[0]-1)t[j+1]+=t[j]/10,t[j]%=10;
64         while(t[t[0]]>=10)
65         {
66             t[t[0]+1]+=t[t[0]]/10;
67             t[t[0]]%=10;
68             ++t[0];
69         }
70     }
71     for(int i=t[0];i;--i)printf("%d",t[i]); printf("\n");
72 }
posted @ 2019-12-20 19:22  蘑菇JJ  阅读(181)  评论(0编辑  收藏  举报