1 条题解
-
2
#include <bits/stdc++.h> #define ll long long #define mod 1000000007 using namespace std; const int N=100005; int n,m,k,s,t,K,b[5][5],c[5][1<<5];// c[i][j] 使用颜色i,集合为j时的可选集合 ll f[N][1<<5],g[1<<5],h[1<<5]; int head[N],tot; ll ans; struct node{ int y,nex; }e[N]; void dfs(int u){ for (int i=head[u];i;i=e[i].nex){ int v=e[i].y; dfs(v); } for (int p=0;p<K;++p){//使用p颜色 memset(g,0,sizeof(g));g[0]=1;//初始化 for (int i=head[u];i;i=e[i].nex){ int v=e[i].y; memset(h,0,sizeof(h)); for (int j=0;j<(1<<K);++j)//枚举当前u的颜色集合 if (g[j]){ int w=c[p][j];//w为合法的颜色集和 for (int k=w;k;k=(k-1)&w){//枚举当前节点v的颜色集合,k始终为w的子集 h[j|k]=(h[j|k]+g[j]*f[v][k])%mod; } } for (int j=0;j<(1<<K);++j)//h数组赋值回g数组 g[j]=h[j]; } for (int j=0;j<(1<<K);++j)//g数组赋值给f[u]数组,不要忘记|(1<<p) f[u][j|(1<<p)]=(f[u][j|(1<<p)]+g[j])%mod; } } int main(){ // freopen("in.txt","r",stdin); int T; cin>>T; while (T--){ cin>>n>>K; for (int i=1;i<=n;++i) { head[i]=0; memset(f[i],0,sizeof(f[i])); } tot=0; int o=0; for (int i=0;i<K;++i) for (int j=0;j<K;++j){ cin>>b[i][j]; --b[i][j]; if (b[i][j]!=b[0][0]) ++o; } for (int i=2;i<=n;++i){ cin>>s; e[++tot]={i,head[s]}; head[s]=tot; } for (int i=0;i<K;++i)//计算c[i][j],首先枚举i和j for (int j=0;j<(1<<K);++j){ c[i][j]=(1<<K)-1;//初始化c[i][j]为全部颜色的集合 for (int k=0;k<K;++k)//枚举j中的每一个元素 if (j&(1<<k)) for (int l=0;l<K;++l) if (b[k][l]!=i || b[l][k]!=i) c[i][j]&=((1<<K)-1-(1<<l)); } dfs(1); ans=0; for (int i=1;i<(1<<K);++i) ans=(ans+f[1][i])%mod; cout<<ans<<"\n"; } }
- 1
信息
- ID
- 491
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 24
- 已通过
- 14
- 上传者