#include <cstdio>
#include <cstring>
const int N = 2e3 + 10, mod = 1e9 + 7;
typedef long long ll; ll C[N][N];
struct edge{ int v, next, w; }E[N << 1]; int p[N], cnt;
inline void init() { memset(p, -1, sizeof p); cnt = 0; }
inline void insert(int u, int v, int w)
{ E[cnt].w = w; E[cnt].v = v; E[cnt].next = p[u]; p[u] = cnt++; }
int size[N]; ll f[N][N], g[N];
void dfs(int u, int fa)
{
size[u] = 1; f[u][1] = 1;
for (int t = p[u], v; t + 1; t = E[t].next)
{
v = E[t].v; if (v == fa) continue;
dfs(v, u);
for (int i = 1; i <= size[u]; i++) g[i] = f[u][i], f[u][i] = 0;
if (E[t].w)
{
//这里0是因为前面有可能一个都没有
//<是因为v在u后面,v子树不可能全部都在u前面
for (int i = 1; i <= size[u]; i++)
for (int j = 0; j < size[v]; j++)
f[u][i + j] = (f[u][i + j] +
C[size[u] + size[v] - i - j][size[v] - j] * C[i + j - 1][j] % mod
* g[i] % mod * (f[v][size[v]] - f[v][j] + mod) % mod) % mod;
}
else
{
//这里1是因为前面至少有个v
//<=是因为v就在u前面,v子树有可能全在u前面
for (int i = 1; i <= size[u]; i++)
for (int j = 1; j <= size[v]; j++)
f[u][i + j] = (f[u][i + j] +
C[size[u] + size[v] - i - j][size[v] - j] * C[i + j - 1][j] % mod
* g[i] % mod * f[v][j] % mod) % mod;
}
size[u] += size[v];
}
for (int i = 1; i <= size[u]; i++) f[u][i] = (f[u][i] + f[u][i - 1]) % mod;
}
int main()
{
int T, n; scanf("%d", &T); char opt[5]; C[0][0] = 1;
for (int i = 1; i <= N; i++)
{
C[i][0] = 1;
for (int j = 1; j <= i; j++)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
}
while (T--)
{
init(); scanf("%d", &n);
for (int i = 1, x, y; i < n; i++)
{
scanf("%d", &x); ++x; scanf("%s", opt); scanf("%d", &y); ++y;
insert(x, y, opt[0] == '<'); insert(y, x, opt[0] == '>');
}
dfs(1, 0);
printf("%lld\n", f[1][n]);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++) f[i][j] = 0;
size[i] = 0;
}
}
return 0;
}
P4099 (虽然不知道为什么调UB要看原题但还是放上吧)
当然也有可能不是UB,求大佬指点/kel 自己实在找不出来了