Description
一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友。每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友。经过N-1次打架之后,整个森林的小猴都会成为好朋友。 现在的问题是,总共有多少种不同的打架过程。 比如当N=3时,就有{1-2,1-3}{1-2,2-3}{1-3,1-2}{1-3,2-3}{2-3,1-2}{2-3,1-3}六种不同的打架过程。
50%的数据N<=10^3。
100%的数据N<=10^6。
方案数mod 9999991。
Solution
结论题
N-1次打架之后形成连通图,实际上可以看做将N-1条边接入图中使其形成树,可以将树化为唯一对应的prufer编码,那么,树的个数实际就是prufer编码的的数目。
由转化prufer编码的方式可知,对于一棵N节点树来说,其prufer编码有N-2位,而生成树的个数就是prufer的个数。那么,就是N^(N-2)个,而加边顺序有(N-1)!种,根据乘法原理,则共有(N-1)!*(N^(N-2))个
Code
#include <stdio.h>
#include <string.h>
typedef long long ll;
const int MOD=9999991;
ll ksm(ll x,ll y) {
ll ret=1;
while (y) {
if (y&1) ret=ret*x%MOD;
x=x*x%MOD;
y>>=1;
}
return ret;
}
int main(void) {
int n; scanf("%d",&n);
ll ans=ksm((ll)n,(ll)(n-2));
for (ll i=1;i<n;i++) ans=ans*i%MOD;
printf("%lld\n", ans);
return 0;
}

本文探讨了一群小猴子通过打架最终成为好友的所有可能过程数量。采用数学方法将问题转化为生成树的数量计算,利用prufer编码理论推导出具体公式,并提供了一段C语言代码实现解决方案。
662

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



