博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ4013 : [HNOI2015]实验比较
阅读量:5311 次
发布时间:2019-06-14

本文共 1185 字,大约阅读时间需要 3 分钟。

首先用并查集将等号缩点,然后拓扑排序判断有没有环,有环则无解,否则通过增加超级源点$0$,可以得到一棵树。

设$f[x][y]$表示$x$子树里有$y$种不同的数字的方案数,由底向上DP。

对于当前点$x$,依次遍历它的所有儿子$y$,设以$x$为根的子树里之前已经有了$s[x]$个点,$y$子树里有$s[y]$个点,那么枚举之前部分里数字种类数$A$,$y$子树里数字种类数$B$,以及合并后用等号连接的数字个数$C$,有$f'[x][A+B-C]+=f[x][A]\times f[y][B]\times C_A^C\times C_{A+B-C}^A$。

因为一对点只会在lca处被DP到,所以时间复杂度为$O(n^3)$。

 

#include
const int N=110,P=1000000007;int n,m,i,j,x,y,c[N][N],fa[N],f[N];int g[N],v[N],nxt[N],ed,dp[N][N],tmp[N],s[N],vis[N],ans;int d[N],h,t,q[N];char op[5];inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;d[y]++;}int F(int x){return fa[x]==x?x:fa[x]=F(fa[x]);}void dfs(int x){ vis[x]=dp[x][0]=1; for(int i=g[x];i;i=nxt[i])if(!vis[v[i]]){ int y=v[i]; dfs(y); for(int A=0;A<=s[x]+s[y];A++)tmp[A]=0; for(int A=0;A<=s[x];A++)for(int B=1;B<=s[y];B++)for(int C=0;C<=A&&C<=B;C++)if(A+B>C) tmp[A+B-C]=(1LL*dp[x][A]*dp[y][B]%P*c[A][C]%P*c[A+B-C][A]+tmp[A+B-C])%P; s[x]+=s[y]; for(int A=0;A<=s[x];A++)dp[x][A]=tmp[A]; } s[x]++; for(int A=s[x];A;A--)dp[x][A]=dp[x][A-1]; dp[x][0]=0;}int main(){ scanf("%d%d",&n,&m); for(c[0][0]=i=1;i<=n;i++)for(c[i][0]=c[i][i]=j=1;j

  

转载于:https://www.cnblogs.com/clrs97/p/5011681.html

你可能感兴趣的文章
一步步教你轻松学奇异值分解SVD降维算法
查看>>
使用pager进行分页
查看>>
UVA - 1592 Database
查看>>
Fine Uploader文件上传组件
查看>>
javascript中的传递参数
查看>>
objective-c overview(二)
查看>>
python查询mangodb
查看>>
consonant combination
查看>>
驱动的本质
查看>>
Swift的高级分享 - Swift中的逻辑控制器
查看>>
Swagger简单介绍
查看>>
Python数据分析入门案例
查看>>
vue-devtools 获取到 vuex store 和 Vue 实例的?
查看>>
Linux 中【./】和【/】和【.】之间有什么区别?
查看>>
内存地址对齐
查看>>
看门狗 (监控芯片)
查看>>
css背景样式
查看>>
JavaScript介绍
查看>>
开源网络漏洞扫描软件
查看>>
yum 命令跳过特定(指定)软件包升级方法
查看>>