[HEOI2013]SAO

题目描述

Welcome to SAO ( Strange and Abnormal Online)。这是一个 VR MMORPG, 含有 n 个关卡。但是,挑战不同关卡的顺序是一个很大的问题。

有 n – 1 个对于挑战关卡的限制,诸如第 i 个关卡必须在第 j 个关卡前挑战, 或者完成了第 k 个关卡才能挑战第 l 个关卡。并且,如果不考虑限制的方向性, 那么在这 n – 1 个限制的情况下,任何两个关卡都存在某种程度的关联性。即, 我们不能把所有关卡分成两个非空且不相交的子集,使得这两个子集之间没有任 何限制。

输入格式

第一行,一个整数 T,表示数据组数。

对于每组数据,第一行一个整数 n,表示关卡数。接下来 n – 1 行,每行为 “i sign j”,其中 0 ≤ i, j ≤ n – 1 且 i ≠ j,sign 为“<”或者“>”,表示第 i 个关卡 必须在第 j 个关卡前/后完成。

输出格式

对于每个数据,输出一行一个整数,为攻克关卡的顺序方案个数,mod 1,000,000,007 输出。

输入输出样例

输入 #1
2 
5 
0 < 2 
1 < 2 
2 < 3 
2 < 4 
4 
0 < 1 
0 < 2 
0 < 3
输出 #1
4 
6

说明/提示

对于 20%的数据有 n ≤ 10。

对于 40%的数据有 n ≤ 100。

对于另外 20%的数据有,保证数据中 sign 只会是<,并且 i < j。

对于 100%的数据有 T ≤ 5,1 ≤ n ≤ 1000。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 struct Node
 8 {
 9     int next,to,w;
10 }edge[2001];
11 int head[1001],num,vis[1001],n;
12 ll size[1005],f[1005][1005],Mod=1e9+7,C[1005][1005],F[1005];
13 void add(int x,int y,int w)
14 {
15     num++;
16     edge[num].next=head[x];
17     edge[num].to=y;
18     head[x]=num;
19     edge[num].w=w;
20 }
21 void dfs(int x)
22 {int i,p1,p3;
23     size[x]=1;f[x][1]=1;
24     vis[x]=1;
25     for (i=head[x];i;i=edge[i].next)
26     {
27         int v=edge[i].to;
28         if (vis[v]) continue;
29         dfs(v);
30         memcpy(F,f[x],sizeof(F));
31         memset(f[x],0,sizeof(f[x]));
32         if (edge[i].w==1)
33         {
34             for (p1=1;p1<=size[x];p1++)
35             for (p3=p1;p3<=p1+size[v]-1;p3++)
36             (f[x][p3]+=C[p3-1][p1-1]*C[size[x]+size[v]-p3][size[x]-p1]%Mod*F[p1]%Mod*(f[v][size[v]]-f[v][p3-p1]+Mod)%Mod)%=Mod;
37         }
38         else 
39         {
40             for (p1=1;p1<=size[x];p1++)
41             for (p3=p1+1;p3<=p1+size[v];p3++)
42             (f[x][p3]+=C[p3-1][p1-1]*C[size[x]+size[v]-p3][size[x]-p1]%Mod*F[p1]%Mod*f[v][p3-p1]%Mod)%=Mod;    
43         }
44         size[x]+=size[v];
45     }
46     for (i=1;i<=size[x];i++)
47     (f[x][i]+=f[x][i-1])%=Mod;
48 }
49 int main()
50 {int T,i,x,y,j;
51 char ch;
52     scanf("%d",&T);
53     C[0][0]=1;
54     for (i=1;i<=1000;i++)
55     {
56         C[i][0]=1;
57         for (j=1;j<=i;j++)
58          C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
59     }
60     while (T--)
61     {
62         scanf("%d",&n);
63         memset(head,0,sizeof(head));
64         memset(edge,0,sizeof(edge));
65         memset(f,0,sizeof(f));
66         memset(vis,0,sizeof(vis));
67         num=0;
68         for (i=1;i<n;i++)
69         {
70             scanf("%d %c %d",&x,&ch,&y);
71             x++;y++;
72             add(x,y,ch=='<');
73             add(y,x,ch=='>');
74         }
75         dfs(1);
76         printf("%lld\n",f[1][n]);
77     }
78 }

 

posted @ 2020-02-02 23:10  Z-Y-Y-S  阅读(115)  评论(0编辑  收藏