[COGS 2353 & 2356] 有标号的DAG计数 容斥原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[COGS 2353 & 2356] 有标号的DAG计数 容斥原理相关的知识,希望对你有一定的参考价值。

COGS 2353

题意

  问 n 个点的带标号 DAG 有多少个.

  n <= 5000 .

分析

  DAG 的突破口在于度数为 0 的点, 我们每次将其删去, 则还有一些度数为 0 的点.

  设 $f_n$ 为 n 个点的带标号 DAG 个数, 奠基 $f_0 = 1$ , 答案为 $f_n$ .

  我们考虑容斥原理, 用至少有 1 个度数为 0 的点的 DAG 个数, 减去至少有 2 个度数为 0 的点的 DAG 个数, 加上至少有 3 个度数为 0 的点的 DAG 个数, ...

  $$f_n = \sum_{k = 1} ^ n {(-1)} ^ {k - 1} \binom{n}{k} 2 ^ {k (n - k)} f_{n - k}$$ .

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 
 7 const int N = 5005;
 8 const int MOD = 10007;
 9 
10 int s, C[N][N], pwr[MOD], f[N];
11 
12 void Prework(void) {
13     C[0][0] = 1;
14     F(i, 1, s) {
15         C[i][0] = 1;
16         F(j, 1, i)
17             C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
18     }
19     
20     pwr[0] = 1;
21     F(i, 1, MOD)
22         pwr[i] = (pwr[i-1] << 1) % MOD;
23 }
24 inline int Pow(int n) { return pwr[n % (MOD - 1)]; }
25 
26 int main(void) {
27     freopen("DAG.in", "r", stdin);
28     freopen("DAG.out", "w", stdout);
29     
30     scanf("%d", &s), Prework();
31 
32     f[0] = 1;
33     F(n, 1, s)
34         F(k, 1, n)
35             f[n] = (f[n] + (k&1 ? 1LL : -1LL) * C[n][k] * Pow(k*(n-k)) * f[n-k]) % MOD;
36     printf("%d\n", (f[s] + MOD) % MOD);
37     
38     return 0;
39 }

 

以上是关于[COGS 2353 & 2356] 有标号的DAG计数 容斥原理的主要内容,如果未能解决你的问题,请参考以下文章

COGS 1534 [NEERC 2004]K小数 &&COGS 930 [河南省队2012] 找第k小的数 可持久化01Trie

cogs 448. 神牛果 神奇&&好理解的思路

COGS103&tyvj1899 [NOIP2002]矩形覆盖

Bzoj1176:Mokia&Cogs1752:[BOI2007]摩基亚Mokia

[BZOJ 1176&COGS 1752][BOI2007]Mokia(CDQ分治)

[uva11722&&cogs1488]和朋友会面Joining with Friend