[除草][HEOI2013]SAO
。。。不好解释
直接上代码:
/** * Problem:SAO * Author:Shun Yao * Time:2013.5.22 * Result:Accepted * Memo:DP */ #include <cstring> #include <cstdlib> #include <cstdio> #define SLL signed long long #define MOD 1000000007 using namespace std; const long Maxn = 1005, Maxm = 10005; long n, siz[Maxn], c[Maxn][Maxn], f[Maxn][Maxn], f1[Maxn][Maxn], pp[Maxn]; char vis[Maxn]; long tot; class gnode { public: long v; gnode *next; gnode(long V, gnode *ne):v(V), next(ne) {} gnode() {} ~gnode() {} } *g[Maxn], *g1[Maxn], *gg[Maxn], *gg1[Maxn], G[Maxm]; void clear(gnode *&g) { g = 0; } void add(gnode *&g, long V) { g = &(G[tot++] = gnode(V, g)); } void dp(long x) { gnode *e; long cur, i, j, k; vis[x] = 1; siz[x] = 1; for (e = g[x]; e; e = e->next) if (!vis[e->v]) { dp(e->v); siz[x] += siz[e->v]; add(gg[x], e->v); } for (e = g1[x]; e; e = e->next) if (!vis[e->v]) { dp(e->v); siz[x] += siz[e->v]; add(gg1[x], e->v); } memset(f[x], 0, sizeof f[x]); f[x][0] = 1; cur = 0; for (e = gg[x]; e; e = e->next) { for (j = 0; j <= siz[x]; ++j) { pp[j] = f[x][j]; f[x][j] = 0; } cur += siz[e->v]; for (j = 0; j <= siz[e->v]; ++j) for (k = j + 1; k <= cur; ++k) f[x][k] = ((SLL)pp[k - j - 1] * (SLL)f[e->v][j] % MOD * (SLL)c[k][j + 1] % MOD * (SLL)c[cur - k][siz[e->v] - j - 1] % MOD + f[x][k]) % MOD; } for (e = gg1[x]; e; e = e->next) { for (j = 0; j <= siz[x]; ++j) { pp[j] = f[x][j]; f[x][j] = 0; } cur += siz[e->v]; for (j = 0; j <= siz[e->v]; ++j) for (k = j; k <= cur; ++k) f[x][k] = ((SLL)pp[k - j] * (SLL)f1[e->v][j] % MOD * (SLL)c[k][j] % MOD * (SLL)c[cur - k][siz[e->v] - j] % MOD + f[x][k]) % MOD; } for (i = 0; i <= siz[x]; ++i) f1[x][i] = f[x][i]; for (i = 1; i <= siz[x]; ++i) f[x][i] = (f[x][i] + f[x][i - 1]) % MOD; for (i = siz[x] - 1; i >= 0; --i) f1[x][i] = (f1[x][i] + f1[x][i + 1]) % MOD; } int main() { static long tt, i, j, x, y; static char ch; memset(c, 0, sizeof c); for (i = 0; i < Maxn; ++i) { c[i][0] = 1; for (j = 1; j <= i; ++j) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD; } scanf("%ld", &tt); while (tt--) { scanf("%ld", &n); tot = 0; for (i = 0; i < n; ++i) { clear(g[i]); clear(g1[i]); clear(gg[i]); clear(gg1[i]); } for (i = 0; i < n - 1; ++i) { scanf("%ld", &x); scanf(" %c", &ch); scanf("%ld", &y); if (ch == '<') { add(g[x], y); add(g1[y], x); } else { add(g[y], x); add(g1[x], y); } } memset(vis, 0, sizeof vis); memset(siz, 0, sizeof siz); dp(0); printf("%ld\n", f[0][n]); } return 0; }
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。