定义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. JavaScript数组 几个常用方法

    前言 数组方法有太多了,本文记录一些本人容易记错的一些数组方法,用于巩固及复习. 后续会慢慢的将其他数组方法添加进来. 善用数组方法可以使数据处理变的优雅且简单. 那下面让我们开始吧: filter( ...

  2. Frida高级逆向-Hook Native(Java So)2

    Frida Hook So 一些操作说明 Native方法第一个参数是 JNIEnv *env 如何在Frida中获取 JNIEnv 对象呢? Java.vm.getEnv(); 如何将string类 ...

  3. Java继承中父类和子类构造函数的问题

    父类有无参构造函数时(显示或隐式),子类的有参和无参构造函数都是默认调用父类的无参构造函数:当父类只有有参构造函数时,子类可以有有参和无参构造函数,子类有参构造函数必须显式调用父类的有参构造函数,子类 ...

  4. Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询

    在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...

  5. 2021.9.9考试总结[NOIP模拟50]

    T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...

  6. Spring源码解读(一):Spring的背景起源及框架整体介绍

    一.前言 Spring起源于2002年Rod Johnson写的一本书<Expert One-on-One J2EE>,书里介绍了Java企业应用程序开发情况,并指出Java EE和EJB ...

  7. VIVADO 2017.4配置MIG IP注意事项

    1.2GB的single rank SODIMMs配置pin还是和以前一样没有问题: 2.8GB SODIMMs配置pin需要注意4点: (1).所有的DDR3引脚都需要在连续的BANK上,例如Z71 ...

  8. 在纯JaveScript中实现报表导出:从“PDF”到“JPG”

    我们在前端报表中完成了各种工作数据的输入或内容处理之后,需要做什么? 数据的导出! 这些数据的常用导出格式有:PDF.Excel.HTML和图片几大类型. 但总有一些实际应用场景,需要的不仅仅是将现有 ...

  9. RocketMQ Consumer 启动时都干了些啥?

    可能我们对 RocketMQ 的消费者认知乍一想很简单,就是一个拿来消费消息的客户端而已,你只需要指定对应的 Topic 和 ConsumerGroup,剩下的就是只需要: 接收消息 处理消息 就完事 ...

  10. 五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

    系列文章 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的 ...