poj-1737 Connected Graph[转] ***

 1 /*
2
3 [转]http://hi.baidu.com/accplaystation/blog/item/51417bdca982bea4cc116660.html
4
5 这道题据说有两种思路:
6
7 1——将总的方案数减掉所有不连通的方案。
8
9 总的方案数是2^(C(n,2)),不连通的方案数可以如下考虑:
10
11 当和点1连通的点数共有k个时,方案数为C(n-1,k)*F(k+1),其他n-k-1各点间任意连边即可,
  方案数为2^(C(n-k-1,2)),所以这样的方案数共有C(n-1,k)*F(k+1)* 2^(C(n-k-1,2))种。
12
13 因此可以得到递推公式:
14
15 F(n)= 2^(C(n,2))-Sum(C(n-1,k)*F(k+1)* 2^(C(n-k-1,2)) | 0<=k<n)
16
17 这种思路的优点在于简单明了,但是缺点在于编程复杂,要算高精度的加、减、乘,2的幂也非常大,
  故某人忽略之……
18

19 2——直接求连通的方案数。
20
21 考虑拿掉点1时点2的情况,设此时点2所在连通块共k各点,这k个点以及剩下的n-k个点分别处在一个连通块中,
  其方案数为F(k)*F(n-k),点2需在除去点1和2的点中取k-1个点构成连通块,故方案数为C(n-2,k-1),
  而这总共k个点与剩下除去点1的n-k-1个点必须通过点1才能连通,即这k个点与点1至少有1条边连通,
  这样的方案数为2^k-1,故这样的情况总共有F(k)*F(n-k)* C(n-2,k-1)*( 2^k-1)种。
22
23 因此可得递推公式为:
24
25 F(n)=Sum(F(k)*F(n-k)* C(n-2,k-1)*( 2^k-1) | 1<=k<n)。
26
27 这种思路虽然理解比较困难,也不知道我解释清楚了没有,汗……但是却极大的减轻了编程的负担,只需要高精度加和乘,
  2的幂只到50 。我的程序就是靠思路二解决的。
28
29 确定了思路,剩下的就是高精度的问题了,当然对于Java者,飘过之……
30
31 核心代码:
32 */
33 void calc(int n)
34
35 {
36
37 int k;
38
39 ans[n].len=1;
40
41 memset(ans[n].num,0,sizeof(ans[n].num));
42
43 Large tmpa,tmpb,tmpc,tmpd;
44
45 for (k=1;k<n;++k)
46
47 {
48
49 Lcopy(ans[n],tmpa);
50
51 Lmul(ans[k],ans[n-k],tmpb);
52
53 Lmul(tmpb,C[n-2][k-1],tmpc);
54
55 Lmulone(tmpc,ptwo[k]-1,tmpd);
56
57 Ladd(tmpa,tmpd,ans[n]);
58
59 }
60
61 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值