挺不错的题啊 然而本蒟蒻一开始一脸懵逼
然后在dalao的指导下 再看了看 注意到有“对每张图片 i,小 D 都最多只记住了某一张质量不比 i 差的另一张图片 Ki。”这么一句话
所以每个点入度就为1,就是一棵树了。
当然先要判断一下有没有环,环的话就输出0 否则就treedp 乘个组合数什么的就好了
如果要看详细题解的推荐这个:传送门
留个代码
#include<bits/stdc++.h>
#define me(a,x) memset(a,x,sizeof a)
using namespace std;
typedef long long LL;
const int N=105,mod=1e9+7;
inline LL read(){
char ch=getchar(); LL x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
return x*f;
}
struct node{int y,next;}a[N]; int len,first[N];
void ins(int x,int y){
a[++len]=(node){y,first[x]},first[x]=len;
}
int c[N][N],fa[N],ax[N],ay[N],al;
int fi(int x){return fa[x]==x?x:fa[x]=fi(fa[x]);}
bool v[N],ok;
void fc(int x){
v[x]=1;
for(int k=first[x];k;k=a[k].next){
if(v[a[k].y]){ok=0; return;}
fc(a[k].y);
}
}
int siz[N],d[N],f[N][N],g[N];
void dfs(int x){
bool o=1;
for(int k=first[x];k;k=a[k].next){
int y=a[k].y; dfs(y);
if(o){
siz[x]=siz[y],o=0;
for(int i=1;i<=siz[x];++i)f[x][i]=f[y][i];
}
else{
me(g,0);
for(int i=1;i<=siz[x];++i)if(f[x][i])
for(int j=1;j<=siz[y];++j)if(f[y][j])
for(int p=max(i,j);p<=i+j;++p)
g[p]=(g[p]+1ll*f[x][i]*f[y][j]%mod*c[p][i]%mod*c[i][j-p+i]%mod)%mod;
siz[x]+=siz[y];
for(int i=1;i<=siz[x];++i)f[x][i]=g[i];
}
}
if(x){
siz[x]++;
if(o)f[x][1]=1;
else for(int i=siz[x];i;--i)f[x][i]=f[x][i-1];
}
}
int main()
{
int n=read(),m=read(),i,j;
for(i=1;i<=n;++i)fa[i]=i;
for(i=0;i<=n;++i)
for(c[i][0]=j=1;j<=i;++j) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
al=0;
for(int i=1;i<=m;++i){
int x=read(); char c; scanf("\n%c",&c);
int y=read();
if(c=='=') x=fi(x),y=fi(y),fa[x]=y;
else ax[++al]=x,ay[al]=y;
}
for(int i=1;i<=al;++i){
int x=fi(ax[i]),y=fi(ay[i]);
if(x==y) return printf("0\n"),0;
ins(x,y),d[y]++;
}
ok=1;
for(int i=1;i<=n;++i) if(!d[i])fc(i);
if(!ok) return printf("0\n"),0;
for(int i=1;i<=n;++i) if(!d[i] && fi(i)==i)ins(0,i);
dfs(0); int ans=0;
for(int i=1;i<=n;++i) ans=(ans+f[0][i])%mod;
printf("%d\n",ans);
return 0;
}