求 DAG 拓扑排序方案数
例题
此题可以直接转化为对
设
若当前的点集为
写了两种写法,一种顺推,一种记搜。都还挺好理解的。
写法一:
int n, m, son[MAXN]; ll f[MAXN];
int main() {
read(n, m);
rep1(i, 1, m) {
int x, y; read(x, y);
son[x] |= 1 << y - 1;
} f[0] = 1;
rep1(s, 0, (1 << n) - 1) rep1(x, 1, n) {
if ((son[x] & s) == son[x] && !(s >> x - 1 & 1)) f[s | (1 << x - 1)] += f[s];
} printf("%lld", f[(1 << n) - 1]);
rout;
}
写法二:
int n, m, son[MAXN]; ll f[MAXN];
il ll dfs(int s) {
if (~f[s]) return f[s];
f[s] = 0;
rep1(i, 1, n) {
int s2 = s ^ (1 << i - 1);
if (s >> (i - 1) & 1 && (son[i] & s2) == son[i]) f[s] += dfs(s2);
} return f[s];
}
int main() {
read(n, m);
rep1(i, 1, m) {
int x, y; read(x, y);
son[x] |= 1 << y - 1;
} f[0] = 1; fill(f + 1, f + (1 << n), -1);
printf("%lld", dfs((1 << n) - 1));
rout;
}