[HNOI2004]树的计数

题目描述

输入输出格式

输入格式:

 

输入文件第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树不超过10^17个。

 

输出格式:

 

输出满足条件的树有多少棵。

 

输入输出样输入样例#1:

4                     
2 1 2 1
输出样例#1:
2

Prüfer编码与Cayley公式

给出几个链接:

http://www.matrix67.com/blog/archives/682

http://blog.csdn.net/justesss/article/details/38129101

http://blog.csdn.net/yuyanggo/article/details/49951597

总的来说,就是说:

1.n个节点的生成树有n^(n-2)

2.对于n个点,度为di

方案数=(n-2)!/(∏(di-1)!)

对于这题直接套第2个公式

分解质因子再化简

注意判断树能否构成

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int d[1001],n,vis[1001],prime[1001],pre[1001],tot,sum;
 7 long long s[1001],ans;
 8 long long qpow(long long x,int y)
 9 {
10     long long res=1;
11     while (y)
12     {
13         if (y&1) res=res*x;
14         x=x*x;
15         y=y/2;
16     }
17     return res;
18 }
19 int main()
20 {
21     int i,j;
22     cin>>n;
23     for (i=1; i<=n; i++)
24     {
25         scanf("%d",&d[i]);
26         if (d[i]==0&&1!=n)
27         {
28             cout<<0;
29             return 0;
30         }
31         sum+=d[i]-1;
32         for (j=2; j<=d[i]-1; j++)
33             s[j]--;
34     }
35     if (sum!=n-2)
36     {
37         cout<<0;
38         return 0;
39     }
40     for (i=2; i<=n-2; i++)
41         s[i]++;
42     for (i=2; i<=n; i++)
43     {
44         if (vis[i]==0)
45         {
46             pre[i]=i;
47             tot++;
48             prime[tot]=i;
49         }
50         for (j=1; j<=tot; j++)
51         {
52             if (prime[j]*i>n) break;
53             vis[i*prime[j]]=1;
54             pre[i*prime[j]]=prime[j];
55             if (i%prime[j]==0) break;
56         }
57     }
58     ans=1;
59     for (i=n; i>=2; i--)
60         if (pre[i]!=i)
61         {
62             s[pre[i]]+=s[i];
63             s[i/pre[i]]+=s[i];
64             s[i]=0;
65         }
66     for (i=n; i>=2; i--)
67     {
68         if (s[i]<0)
69         {
70             cout<<0;
71             return 0;
72         }
73         ans*=qpow(i,s[i]);
74     }
75     cout<<ans;
76 }

 

posted @ 2017-10-07 21:47  Z-Y-Y-S  阅读(371)  评论(0编辑  收藏  举报