传送门

首先根据题目条件,题目中如果是=的点可以缩起来,然后\(a<b\)连边\(a\rightarrow b\),而且所有点入度为最多1,那么判掉有环的不合法情况,题目中的依赖关系就是一颗外向树森林,可以通过建一个另外的点向每棵树的根连边,能得到一颗外向树

然后就是dp,这里把打等号的一些相邻的数看成一个数,设\(f_{i,j}\)表示i点子树序列长度为j的方案,转移将儿子依次合并,即\(f_{x,l}\leftarrow f_{x,j}*f_{y,k}*g_{j,k,l}\)

上面的g是一个长度为j一个长度为k的序列合并成长度为l的序列方案数,转移枚举最后一个数是第一个序列的,第二个序列的或者是合并起来的

#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register using namespace std;
const int N=100+10,mod=1e9+7;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],dg[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++dg[y];
}
int f[N][N],g[N][N][N<<1],d[N],sz[N];
void dp(int x)
{
sz[x]=f[x][0]=1;
for(int h=hd[x];h;h=nt[h])
{
int y=to[h];
dp(y);
memset(d,0,sizeof(d));
for(int i=0;i<sz[x];++i)
for(int j=1;j<=sz[y];++j)
for(int k=1;k<=i+j;++k)
d[k]=(d[k]+1ll*f[x][i]*f[y][j]%mod*g[i][j][k]%mod)%mod;
sz[x]+=sz[y];
memcpy(f[x],d,sizeof(d));
}
for(int i=sz[x];i;--i) f[x][i]=f[x][i-1];
f[x][0]=0;
}
int n,m,e[N][2],ff[N];
il int findf(int x){return ff[x]==x?x:ff[x]=findf(ff[x]);}
bool v[N];
bool check(int x)
{
if(v[x]) return 0;
v[x]=1;
for(int h=hd[x];h;h=nt[h]) if(!check(to[h])) return 0;
v[x]=0;
return 1;
} int main()
{
n=rd(),m=rd();
for(int i=1;i<=n;++i) ff[i]=i;
for(int i=1;i<=m;++i)
{
int x=rd(),z=(getchar()=='<'),y=rd();
if(!z) --m,--i,ff[findf(x)]=findf(y);
else e[i][0]=x,e[i][1]=y;
}
for(int i=1;i<=m;++i) add(findf(e[i][0]),findf(e[i][1]));
for(int i=1;i<=n;++i)
if(findf(i)==i&&!check(i)) return puts("0"),0;
for(int i=1;i<=n;++i)
if(!dg[i]&&findf(i)==i) add(n+1,i);
g[0][0][0]=1;
for(int i=0;i<=n;++i)
for(int j=0;j<=n;++j)
for(int k=1;k<=i+j;++k)
{
if(i) g[i][j][k]=(g[i][j][k]+g[i-1][j][k-1])%mod;
if(j) g[i][j][k]=(g[i][j][k]+g[i][j-1][k-1])%mod;
if(i&&j) g[i][j][k]=(g[i][j][k]+g[i-1][j-1][k-1])%mod;
}
dp(n+1);
int ans=0,lim=1;
for(int i=1;i<=n;++i) lim+=findf(i)==i;
for(int i=1;i<=lim;++i) ans=(ans+f[n+1][i])%mod;
printf("%d\n",ans);
return 0;
}

luogu P3240 [HNOI2015]实验比较的更多相关文章

  1. BZOJ 4013/Luogu P3240 [HNOI2015] 实验比较 (树形DP)

    题目传送门 分析 放一个dalao博客: xyz32768 的博客,看完再回来看本蒟蒻的口胡吧(其实嘛-不回来也行) 精髓是合并的方案数的计算,至于为什么是Ci−1j−1\large C_{i-1}^ ...

  2. P3240 [HNOI2015]实验比较 树形DP

    \(\color{#0066ff}{ 题目描述 }\) 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 \(N\) 张图片,编号为 \(1\) 到\(N\).实验分若 ...

  3. 【BZOJ4013】[HNOI2015]实验比较(动态规划)

    [BZOJ4013][HNOI2015]实验比较(动态规划) 题面 BZOJ 洛谷 题解 看题目意思就是给你一棵树,连边表示强制顺序关系.然后你要给点染色,在满足顺序关系的情况下,将序列染成若干个颜色 ...

  4. 4013: [HNOI2015]实验比较

    4013: [HNOI2015]实验比较 链接 分析: 首先把等号用并查集合并起来. 由于只存在最多一个质量不比i差的数,发现这是森林.若x<y,连边x->y.于是建虚拟根节点0. 然后树 ...

  5. [BZOJ4013][HNOI2015]实验比较(树形DP)

    4013: [HNOI2015]实验比较 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 756  Solved: 394[Submit][Status] ...

  6. bzoj 4013: [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  7. [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  8. BZOJ4013 : [HNOI2015]实验比较

    首先用并查集将等号缩点,然后拓扑排序判断有没有环,有环则无解,否则通过增加超级源点$0$,可以得到一棵树. 设$f[x][y]$表示$x$子树里有$y$种不同的数字的方案数,由底向上DP. 对于当前点 ...

  9. Luogu P3239 [HNOI2015]亚瑟王

    题目链接 \(Click\) \(Here\) 期望神题.最开始一直尝试推朴素一点的,逻辑上的\(DP\)式子,后来发现一直出锅,可能是我的式子没容斥对... 题解中给出的想法是这样的: 首先,如果直 ...

随机推荐

  1. NoSQL还是SQL?这一篇讲清楚

    https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=2653550127&idx=1&sn=93f79e007d757a ...

  2. [HEOI2014]平衡

    [HEOI2014]平衡 转化为求选择k个数,和为(n+1)*k的方案数 保证,每个数[1,2*n+1]且最多选择一次. 限制k个很小,所以用整数划分的第二种方法 f[i][j],用了i个,和为j 整 ...

  3. QTREE6&&7 - Query on a tree VI &&VII

    树上连通块 不用具体距离,只询问连通块大小或者最大权值 可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等 一个trick,两个LCT分离颜色 每个颜色在边上. 仅保留连通块顶部不 ...

  4. luogu3731 新型城市化

    题目链接 思路 这道题对于题意的转化很关键. 题目要求的是添上一条边,使得图中最大团的大小变大.给出的边是原图的补集,这就给我们了提示. 因为题目中说,原图中最多有两个团.所以给出的边一定形成了一个二 ...

  5. SQL问题+知识点总结总

    1.SQL中的内置函数有哪些?(Count.Sum.Avg.Max.Min) 2.SQL查询语句的执行顺序.(先执行from语句,再执行条件语句,最后执行Select 语句投影查询信息) 3.Havi ...

  6. java基本数据类型转换溢出问题

    java的基本数据类型有(int.byte.double.float.char.boolean.long.short):这里介绍整型数据 示例1: public class H_Z01 { publi ...

  7. plink提取指定样本的数据(keep函数)

    提取样本见命令行: plink --bfile file --noweb --keep sampleID.txt --recode --make-bed --out sample 其中,sampleI ...

  8. Freemarker 的 Eclipse 插件 安装

    clipse版本(目前最新oxygen) 如果你的eclipse版本为Oxygen "Help" ---> "Eclipse Marketplace..." ...

  9. 高级组件——进度条 JProgressBar

    JProgressBar pro=new JProgressBar(); pro.setIndeterminate(boolean); 设置不确定性        false,确定的进度条(显示进度, ...

  10. opencv: 排序

    opencv提供了排序函数:  sort和sorIdx , 其中sortIdx可以获取排序后的序号,比较方便: sortIdx原型: C++: void sortIdx(InputArray src, ...