[noi31]MST
定义 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]