题目
题意:
对于一个n个点的图,每对点 u , v u,v u,v间有 p 0 p_0 p0​的几率没有边, p 1 p_1 p1​的几率有权值为1的边, p 2 p_2 p2​…边权 &lt; = 4 &lt;=4 <=4,对于 n − 1 &lt; = t &lt; = ( n − 1 ) ( m a x v a l o f e d g e ) n-1&lt;=t&lt;=(n-1)(maxval \ of \ edge) n−1<=t<=(n−1)(maxval of edge)的每个 t t t求有最小生成树且最小生成树大小为 t t t的几率 ( m o d 1000000007 ) \pmod {1000000007} (mod1000000007)

考虑克鲁斯卡尔求生成树的过程,那么我们可以从小到大加入边,在 d p dp dp上即为 f i , j f_{i,j} fi,j​表示 &lt; = i &lt;=i <=i的边联通特定的 j j j个点的概率。
发现不好转移,但是还是可以转移的。
枚举特定的点中标号最小的点所在的由 &lt; = i − 1 &lt;=i-1 <=i−1的边联通的极大联通块大小,这个联通块往外连的边中考虑边权为 i i i的边,它连向了一个由 &lt; = i &lt;=i <=i的边联通的且不包含当前联通块的极大联通块,这个联通块是比标号最小的点所在的由 &lt; = i &lt;=i <=i的边联通的极大联通块小的,是一个子问题,那么它的方案数是可以在之前就计算出来的,相当于一个点有很多个儿子,我们从小到大枚举儿子子树大小然后枚举这个大小的有多少个再组合数分配标号去重,这样就可以转移了。
但是我们这样只算了联通的概率,并没有计算最小生成树的值。。。。。。
那么就再来一维?
我们用生成函数表示最后一维, x t x^t xt前的系数表示权值为 t t t的最小生成树的方案。
因为我们可以发现我们之前这个究极复杂的DP是可以算最小生成树的值的。
然后用 x = 0... ( n − 1 ) ( m a x v a l o f e d g e − 1 ) x=0...(n-1)(maxval \ of \ edge - 1) x=0...(n−1)(maxval of edge−1)带入计算答案然后插值得到多项式即可。

原题解(有几处(官方)错误):
记 f i , j f_{i,j} fi,j​ 表示 i 个点的图由权值$ ≤ t $的边连通的概率,初值 f 0 , 1 = 1 ; f 0 , j = 0 ( 2 ≤ j ≤ n ) f_{0,1} = 1; f_{0,j} = 0 (2 ≤ j ≤ n) f0,1​=1;f0,j​=0(2≤j≤n)。
假设 f i , j ( 0 ≤ i ≤ t − 1 ; 1 ≤ j ≤ n ) f_{i,j} (0 ≤ i ≤ t − 1; 1 ≤ j ≤ n) fi,j​(0≤i≤t−1;1≤j≤n)均已求出,当前考虑到权值为 t 的边。考虑一个 dfs 由 ≤ t 的边
构成的连通块的过程:从 1 号点所在的由 ≤ t − 1 ≤ t − 1 ≤t−1的边构成的连通块出发,按照从小到大的顺序递归访
问其他由 ≤ t 的边构成的连通块(大小相同则优先访问块内最小编号较小的)。现在 dp 这个 dfs 过程,
记 g t , i , j g_{t,i,j} gt,i,j​表示从 1 号点所在的由 ≤ t − 1 ≤ t − 1 ≤t−1 的边构成的大小为 i 的连通块出发,已经访问过的其他由 ≤ t 的
边构成的连通块大小之和是 j 的概率,按照由 ≤ t ≤ t ≤t 的边构成的连通块的大小 s 从小到大考虑,先计算出
f t , s f_{t,s} ft,s​,再枚举 g t , i , j g_{t,i,j} gt,i,j​ 挂上多少个大小为 s 的连通块,需要和挂上的连通块之间连 ≥ t ≥ t ≥t 的边或者不连边,但
是至少有一条权值为 t 的边,并且挂上的连通块之间两两不能连权值 ≤ t ≤ t ≤t 的边。不难分析这样 dp 一次
的复杂度是 O ( k n 3 l o g n ) O(kn^3 log n) O(kn3logn)。
至此还没有考虑最小生成树,为了避免在状态里额外记录权值和,每挂上一个大小为 s 的连通块就
给概率额外乘上 x s − 1 x_{s−1} xs−1​,最后会得到一个关于 x 的多项式,其中 x t x^t xt 项的系数就是最小生成树是 t + ( n − 1 ) t+ (n−1) t+(n−1)
的概率,分别取 x = 0 ; 1 ; 2 ; 3 , ( k − 1 ) ( n − 1 ) x = 0; 1; 2; 3,(k − 1)(n − 1) x=0;1;2;3,(k−1)(n−1) 代入求值,最后使用插值或者高斯消元求出多项式即可。

另外标程对于 x i = i , 0 &lt; = i &lt; = n x_i=i,0&lt;=i&lt;=n xi​=i,0<=i<=n的拉格朗日插值求多项式的方法十分巧妙(我精简后的代码只有7行)。
对于把 0 0 0也带入的连续整数的拉格朗日插值。
对于 y j y_j yj​后面乘上的式子的分母不是 1 1 1开始的那种 ( − 1 ) n − j ( j − 1 ) ! ( n − j ) ! (-1)^{n-j}(j-1)!(n-j)! (−1)n−j(j−1)!(n−j)!,而是 ( − 1 ) n − j j ! ( n − j ) ! (-1)^{n-j}j!(n-j)! (−1)n−jj!(n−j)!
这样我们就可以用巧妙的累和而不是直接计算求出系数。

for(int j=n;j&gt;=i;j--) a[j]=1ll*(a[j]-a[j-1])*inv[i] \texttt{ for(int j=n;j&gt;=i;j--) a[j]=1ll*(a[j]-a[j-1])*inv[i]}  for(int j=n;j>=i;j--) a[j]=1ll*(a[j]-a[j-1])*inv[i]
这一行中,每一个 a j a_j aj​会对 a i a_i ai​贡献 ( i j ) ÷ i ! ∗ a [ j ] \binom{i}{j} \div {i!} * a[j] (ji​)÷i!∗a[j],恰好就是 a [ j ] j ! ( i − j ) ! \frac {a[j]}{j!(i-j) !} j!(i−j)!a[j]​

s[j] = ((j?s[j-1]:0) - (i-1ll) * s[j]) \texttt{s[j] = ((j?s[j-1]:0) - (i-1ll) * s[j])} s[j] = ((j?s[j-1]:0) - (i-1ll) * s[j])
这一行中, s [ j ] s[j] s[j]存的是前 i − 2 i-2 i−2个数(包括 0 , 1 , 2... i − 1 0,1,2...i-1 0,1,2...i−1)选择 j j j个他们的乘积和。
然后再加乘起来就刚好是答案,太巧也太强了。

#include<bits/stdc++.h>
#define maxn 41
#define mod 1000000007
using namespace std;int n,k;
int f[5][maxn],sp[6],p[5],g[maxn][maxn],tr[maxn][maxn],tb[maxn][maxn];
int Pow(int base,int k){int ret = 1;for(;k;k>>=1,base=1ll*base*base%mod)if(k&1)ret=1ll*ret*base%mod;return ret;
}int inv[maxn*maxn]={1,1},fac[maxn*maxn]={1,1},invf[maxn*maxn]={1,1},c[maxn*maxn][maxn*maxn],pw[maxn*maxn];vector<int>interpolation(vector<int>a,int n){// only when x_i = i , 0 <= i <= nvector<int>s(n+1),r(n+1);r[0]=a[0],s[0]=1;for(int i=1;i<=n;i++){for(int j=n;j>=i;j--) a[j]=1ll*(a[j]-a[j-1])*inv[i]%mod;for(int j=i;j>=0;j--)s[j] = ((j?s[j-1]:0) - (i-1ll) * s[j]) % mod,r[j] = (r[j] + s[j] * 1ll * a[i]) % mod;}return r;
}int main(){int T;c[0][0] = 1;for(int i=1;i<maxn*maxn;i++){c[i][0] = 1;for(int j=1;j<=i;j++)c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod;}for(int i=2;i<maxn*maxn;i++)fac[i] = 1ll * fac[i-1] * i % mod,inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod,invf[i] = 1ll * invf[i-1] * inv[i]  %mod;for(scanf("%d",&T);T--;){scanf("%d%d",&n,&k);for(int i=0;i<=k;i++) scanf("%d",&p[i]) , p[i] = p[i] * 1ll * Pow(100,mod-2) % mod;sp[k+1] = p[0];for(int i=k;i>=0;i--) sp[i] = (sp[i+1] + p[i]) % mod;vector<int>ar;for(int x=0;x<=(k-1)*(n-1);x++){ memset(f,0,sizeof f);f[0][1] = 1;pw[0] = 1;for(int i=1;i<=n;i++) pw[i] = pw[i-1] * 1ll * x % mod;for(int t=1;t<=k;t++){memset(g,0,sizeof g);for(int i=0;i<=n;i++)for(int j=0;j+i<=n;j++){tb[i][j] = Pow(sp[t+1],i*j);tr[i][j] = (Pow(sp[t],i*j)-tb[i][j]) % mod;}for(int i=1;i<=n;i++)g[i][0] = 1;for(int s=1;s<=n;s++){for(int i=1;i<=s;i++) f[t][s] = (f[t][s] + 1ll * g[i][s-i] * c[s-1][i-1] % mod * f[t-1][i]) % mod;for(int i=1;i<=n;i++)for(int j=n-i;j>=0;j--)for(int k=1,sum=1,cr=1ll*tr[i][s]*f[t][s]%mod*pw[t-1]%mod;k*s+j<=n-i;k++){sum = 1ll * sum * cr % mod * tb[(k-1)*s+j][s] % mod * c[k*s+j][s] % mod;g[i][k*s+j] = (g[i][k*s+j] + 1ll * sum * g[i][j] % mod * invf[k]) % mod;}}}ar.push_back(f[k][n]);}ar = interpolation(ar,(k-1)*(n-1));for(int i=0;i<=(k-1)*(n-1);i++)printf("%d%c",(ar[i]+mod)%mod," \n"[i==(k-1)*(n-1)]);}
}

HDU 6691 Minimum Spanning Trees相关推荐

  1. HDU 4408 Minimum Spanning Tree 最小生成树计数

    http://acm.hdu.edu.cn/showproblem.php?pid=4408 题意:求最小生成树个数 题解:对于Kruskal算法,我们发现,最小生成树要想用多种方法就要有长度相同的边 ...

  2. Lecture 16 Minimum Spanning Trees

  3. hdu 4408 Minimum Spanning Tree

    题目连接:点击打开链接 解法:利用kruskal算法 把图划分成森林, 同一点有相同最小的权值到别的点, 通过determinant计算树的课数. 总结:模板 + 自己不太懂 = 记录 + 重新学 代 ...

  4. HDU 4408 - Minimum Spanning Tree(最小生成树计数)

    有边权的最小生成树计数 模板 #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostre ...

  5. Directed Minimum Spanning Tree: Chu-Liu/Edmonds Algorithm

    我们的现代数据库大作业要求实现一个图查询系统,包括基于属性的子图查询.可达性查询(可选).最短路径查询(可选).TopK最短路径查询(可选).图形化展示(可选)等功能.分成子图同构查询小组以及可达性及 ...

  6. Minimum spanning tree HDU - 6954

    Minimum spanning tree HDU - 6954 题意: 给定n-1个点,编号从2到n,两点a和b之间的边权重为lcm(a,b).请找出它们形成的最小生成树. 2<=n<= ...

  7. leetcode310. Minimum Height Trees

    题目 For an undirected graph with tree characteristics, we can choose any node as the root. The result ...

  8. HDU 1385 Minimum Transport Cost

    HDU 1385 Minimum Transport Cost 我的WA代码 AC的代码 我的WA代码 我的大概思路就是,如果i->j,如果找到一个中间点k就直接简单的将path[i][j]=k ...

  9. 《Boost》Part1 Minimum Spanning Tree

    <Boost>Part1 Minimum Spanning Tree 1.Boost中的最小生成树介绍 MST最小生成树,是图论中的基本算法,还有一种是最大生成树,此处暂不介绍. 最小生成 ...

最新文章

  1. Selenium_python自动化环境搭建篇
  2. CSS中background-position的使用
  3. SpringCloud教程-注册中心(Consul)(SpringCloud版本Greenwich.SR4)
  4. stm32之ADC应用实例(单通道、多通道、基于DMA)
  5. Monthly Expense POJ - 3273(二分最大值最小化)
  6. 欢迎使用CSDN-markdown编辑器132133
  7. 阿里云MySQL及Redis灵异断连现象:安全组静默丢包解决方法
  8. python 共享文件_通过 Python 快速实现局域网内文件共享
  9. 焊接工时简便计算工具_焊接工时计算表
  10. python数据标注工具_数据标注工具大全汇总,有了这些工具再也不用自己开发了...
  11. 买笔记本电脑主要看什么?
  12. golang-亚马逊s3上传图片文件
  13. 分门别类刷leetcode——动态规划(C++实现)
  14. 类似于计算机的文件管理器,XYplorer 21比电脑自带的文件管理器还好用的工具
  15. 拆解SSK SCRM330 USB3.0读卡器 GL3233 固件 0819
  16. 中医卫统直报、重点专科、绩效考核病案首页字段汇总-标出差异
  17. Calcite执行计划的四种展示格式
  18. 最新九月百度人搜,阿里巴巴,腾讯华为小米搜狗笔试面试三十题
  19. android 支付sdk流程,支付SDK
  20. Angular页面出不来,显示空白页面。。。

热门文章

  1. 深度学习的简介、领域、框架和实际应用概述
  2. 微信小程序-创建小程序+编写学生评教系统的学生登录页面
  3. 排队论,对策论,层次分析法
  4. ThinkPad平板电脑在定价上还存在的一个问题是
  5. 视频编码第一节:H.265/HEVC原理——入门
  6. 深度!推动“企业上云”光有补贴不够,还要看这5点
  7. 获取QQ企业邮箱通讯录PY脚本
  8. oracle递归查询用法
  9. oracle递归查询(层级查询)
  10. 从315晚会曝光网秦谈企业社会责任