题目链接
1 #include <stdio.h>
2 #include <algorithm>
3 #include <string.h>
4 #include <iostream>
5 using namespace std;
6 typedef long long ll;
7
8 inline int read()
9 {
10 int x=0,f=1;char ch=getchar();
11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13 return x*f;
14 }
15
16 /********************************************************************/
17
18 const int maxn = 25;
19 int n, m;
20 int dp[(1<<20)+5];
21 int ok[maxn][maxn];
22
23 void solve(){
24 dp[0] = 1;
25 for(int i = 1;i <= n;i++){
26 for(int j = (1<<m);j >= 0;j--){
27 if(dp[j]){ //j状态有i-1头牛
28 for(int k = 1;k <= m;k++){ //每一个牛棚
29 if(ok[i][k] && (j != (j|(1<<(k-1)))))
30 dp[j|(1<<(k-1))] += dp[j];
31 }
32 }
33 dp[j] = 0;
34 }
35 }
36 int ans = 0;
37 for(int i = 0;i < (1<<m);i++){
38 ans += dp[i];
39 }
40 printf("%d
", ans);
41 return;
42 }
43
44 int main(){
45 while(~scanf("%d%d", &n ,&m)){
46 memset(ok, 0, sizeof(ok));
47 memset(dp, 0, sizeof(dp));
48
49 for(int i = 1;i <= n;i++){
50 int a, b;
51 a = read();
52 while(a--){
53 b = read();
54 ok[i][b] = 1;
55 }
56 }
57 solve();
58 }
59 return 0;
60 }