BZOJ 4013: [HNOI2015]实验比较

来源:互联网 发布:八爪鱼数据采集能干嘛 编辑:程序博客网 时间:2024/05/21 05:59

挺不错的题啊 然而本蒟蒻一开始一脸懵逼

然后在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;}
原创粉丝点击