http://www.lydsy.com/JudgeOnline/problem.php?id=1211 (题目链接)
题意
一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。
Solution
prufer序列,明明的烦恼简化版。
代码
// bzoj1211 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<map> #define inf 2147483640 #define LL long long #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=200; int d[maxn],a[maxn],np[maxn],n; void pls(int x,int f) { for (int i=2;i<=x;i++) if (!np[i]) for (int j=i;j<=x;j*=i) a[i]+=f*x/j; } int main() { np[1]=1; for (int i=2;i<=150;i++) if (!np[i]) for (int j=i*2;j<=150;j+=i) np[j]=1; scanf("%d",&n); int sum=0; if (n==1) { int x;scanf("%d",&x); if (!x) printf("1"); else printf("0"); return 0; } for (int i=1;i<=n;i++) { scanf("%d",&d[i]); if (!d[i]) {printf("0");return 0;} d[i]--; sum+=d[i]; pls(d[i],-1); } if (sum!=n-2) {printf("0");return 0;} LL ans=1; pls(sum,1); for (int i=2;i<=150;i++) for (int j=1;j<=a[i];j++) ans*=(LL)i; printf("%lld",ans); return 0; }