[除草][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;

}

 

你可能感兴趣的:(SA)