定义dp[i]表示当前连通块状态为i的方案数(状态记录该状态每一个连通块的大小),那么从小到大枚举每条边,考虑这条边在不在最小生成树上:

1. 如果不在最小生成树上,那么这条边有$\sum_{i=1}^{scc}\sum_{j=i+1}^{scc}Si\cdot Sj$(Si表示第i个连通块的点数)种位置,即每一个状态的方案都乘上这个数;

2. 如果在最小生成树上,那么他一定会把某两个连通块连起来,枚举这两个连通块并递推到新的状态。

那么这样的时间复杂度是多少呢?大约是$o(Pn\cdot n^{3})$(Pn表示将n划分成一些数的和的方案数,$P_{40}\approx 40000$,$n^{2}$是枚举连通块,另一个n是hash的时间),显然这样是会炸掉的……

似乎这个状态的记录方式可以改变,可改为每一个大小的连通块出现次数,由于最多只有$\sqrt{n}$种方案,枚举两个连通块也仅有n的时间复杂度,总时间复杂度降为$o(Pn\cdot n^{2})$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define mod 1000000007
4 map<int,int>vis;
5 int n,m,k,di[40001][41],a[41],mi[41],b[1001],f[40001];
6 vector<int>vec[40001];
7 void dfs(int k,int s,int p){
8 if (!s){
9 memcpy(di[++m],a,sizeof(a));
10 di[m][0]=k;
11 }
12 if (s<1)return;
13 k++;
14 for(int i=1;i<=p;i++){
15 a[i]++;
16 dfs(k,s-i,i);
17 a[i]--;
18 }
19 }
20 int ha(int k){
21 int ans=0;
22 for(int i=1;i<=n;i++)ans=(ans+1LL*mi[i]*di[k][i])%mod;
23 return ans;
24 }
25 int main(){
26 mi[0]=1;
27 for(int i=1;i<=40;i++)mi[i]=mi[i-1]*41LL%mod;
28 scanf("%d",&n);
29 dfs(0,n,n);
30 for(int i=1;i<=m;i++)vec[di[i][0]].push_back(i);
31 for(int i=1;i<n;i++){
32 scanf("%d",&k);
33 b[k]=1;
34 }
35 f[1]=1;
36 m=n*(n-1)/2;
37 k=n;
38 for(int i=1;i<=m;i++)
39 if (!b[i])
40 for(int j=0;j<vec[k].size();j++){
41 int v=vec[k][j],s=m-i+1;
42 for(int x=1;x<=n;x++)
43 for(int y=x+1;y<=n;y++)s-=di[v][x]*di[v][y]*x*y;
44 for(int x=1;x<=n;x++)s-=(di[v][x]-1)*di[v][x]*x*x/2;
45 f[vec[k][j]]=f[vec[k][j]]*1LL*s%mod;
46 }
47 else{
48 for(int j=0;j<vec[k-1].size();j++)vis[ha(vec[k-1][j])]=vec[k-1][j];
49 for(int j=0;j<vec[k].size();j++){
50 int v=vec[k][j];
51 for(int x=1;x<=n;x++)
52 for(int y=x+1;y<=n-x;y++){
53 if ((!di[v][x])||(!di[v][y]))continue;
54 di[v][x]--;
55 di[v][y]--;
56 di[v][x+y]++;
57 f[vis[ha(v)]]=(f[vis[ha(v)]]+f[v]*(di[v][x]+1LL)*(di[v][y]+1)*x*y)%mod;
58 di[v][x]++;
59 di[v][y]++;
60 di[v][x+y]--;
61 }
62 for(int x=1;x<=n/2;x++)
63 if (di[v][x]>1){
64 di[v][x]-=2;
65 di[v][x+x]++;
66 f[vis[ha(v)]]=(f[vis[ha(v)]]+f[v]*(di[v][x]+2LL)*(di[v][x]+1)*x*x/2)%mod;
67 di[v][x]+=2;
68 di[v][x+x]--;
69 }
70 }
71 k--;
72 for(int j=0;j<vec[k].size();j++)vis[ha(vec[k][j])]=0;
73 }
74 printf("%d",f[vec[1][0]]);
75 }

[noi31]MST的更多相关文章

  1. POJ1679 The Unique MST[次小生成树]

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28673   Accepted: 10239 ...

  2. 基于MST的立体匹配及相关改进(A Non-Local Cost Aggregation Method for Stereo Matching)

    怀着很纠结的心情来总结这篇论文,这主要是因为作者提虽然供了源代码,但是我并没有仔细去深究他的code,只是把他的算法加进了自己的项目.希望以后有时间能把MST这一结构自己编程实现!! 论文题目是基于非 ...

  3. BZOJ 2654 & 玄学二分+MST

    题意: 给一张图,边带权且带颜色黑白,求出一棵至少包含k条白边的MST SOL: 正常人都想优先加黑边或者是白边,我也是这么想的...你看先用白边搞一棵k条边的MST...然后维护比较黑边跟白边像堆一 ...

  4. LA 5713 秦始皇修路 MST

    题目链接:http://vjudge.net/contest/144221#problem/A 题意: 秦朝有n个城市,需要修建一些道路使得任意两个城市之间都可以连通.道士徐福声称他可以用法术修路,不 ...

  5. [poj1679]The Unique MST(最小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28207   Accepted: 10073 ...

  6. [BZOJ2654]tree(二分+MST)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2654 分析:此题很奇葩,我们可以给所有白边加上一个权值mid,那么在求得的MST中白边 ...

  7. CodeForces 125E MST Company

    E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...

  8. 2015baidu复赛2 连接的管道(mst && 优先队列prim)

    连接的管道 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)

    判别MST是否唯一的例题. POJ1679-The Unique MST 题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique! 题解:MST是否唯一取决于是否有 ...

随机推荐

  1. SONiC架构分析

    目录 系统架构 设计原则 核心组件 SWSS 容器 syncd 容器 网络应用容器 内部通信模型 SubscriberStateTable NotificationProducer/Consumer ...

  2. Parameter index out of range(1 > number of parameters, which is 0)参数索引超出范围

    今天在写项目的过程中,有一个模块是做多选删除操作,通过servlet获得多选框的value组,然后执行sql操作.如下: 1 @RequestMapping( "/delteCouse.do ...

  3. 初次认识指针:C语言*p、p以及&p的区别,*p和**p的区别?

    https://blog.csdn.net/weixin_43115440/article/details/93475460 先要理解地址和数据,你可以想象有很多盒子,每个盒子有对应的号码,那个号码叫 ...

  4. javascript运算符和表达式

    1.表达式的概念 由运算符连接操作组成的式子,不管式子有多长,最终都是一个值. 2.算术运算符 加+ 减- 乘* 除/ 取模% 负数- 自增++ 自减-- 3.比较运算符 等于==  严格等于=== ...

  5. 【Java虚拟机9】类加载器之命名空间详解

    前言 前面介绍类加载器的时候,介绍了一下命名空间这个概念.今天就通过一个例子,来详细了解一下[类加载器的命名空间].然后通过这个例子,我们可以总结一下双亲委托模型的好处与优点. 例1(不删除class ...

  6. Linux主机入侵检测

    检查系统信息.用户账号信息 ● 操作系统信息 cat /proc/version 用户信息 用户信息文件 /etc/passwd root:x:0:0:root:/root:/bin/bash 用户名 ...

  7. 改善深层神经网络-week1编程题(Initializaion)

    Initialization 如何选择初始化方式,不同的初始化会导致不同的结果 好的初始化方式: 加速梯度下降的收敛(Speed up the convergence of gradient desc ...

  8. Vue接收后端传过来excel表格的文件流并下载

    题外话:当接收文件流时要确定文件流的类型,但也有例外就是application/octet-stream类型,主要是只用来下载的类型,这个类型简单理解意思就是通用类型类似 var .object.ar ...

  9. Python:Ubuntu上使用pip安装opencv-python出现错误

    Ubuntu 18.04 上 使用 pip 安装 opencv-python,出现的错误如下: 1 ~$: pip install opencv-python -i https://pypi.tuna ...

  10. web性能检测工具lighthouse

    About Automated auditing, performance metrics, and best practices for the web. Lighthouse 可以自动检查Web页 ...