定义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. SphereEx 创始人张亮云咖访谈回顾:构建数据服务的新思路

    2021 年 7 月 21 日,2021 亚马逊云科技中国峰会在上海盛大开幕.本次大会以"构建新格局,共赢云时代"为主题,邀请到来自技术社区.开源软件基金会.开源创业代表.女性开发 ...

  2. 解决VM 与 Device/Credential Guard 不兼容

    通过命令关闭Hyper-V(控制面板关闭Hyper-V起不到决定性作用,要彻底关闭Hyper-V) 以管理员身份运行Windows Powershell (管理员)(Windows键+X) 运行下面命 ...

  3. CF193D Two Segments (线段树+dp)(外加两个扩展题)

    大概算是个系列整理 (最强版是模拟赛原题)) 首先,我们先来看这个题目. QWQ一开始是毫无头绪,除了枚举就是枚举 首先,我们可以枚举一个右端点,然后算一下当前右端点的答案 我们令\(f[l,r]\) ...

  4. 洛谷2046 NOI2010海拔

    QwQ题目太长 这里就不复制了 题目 这个题...算是个比较经典的平面图最小割变成对偶图的最短路了QwQ 首先考虑最小割应该怎么做. 有一个性质,就是每个点的海拔要么是1,要么是0 QwQ不过这个我不 ...

  5. g++ 常用命令

    g++ --help

  6. K12教培从业者转型指南 换个赛道依然可以再创辉煌

    随着"双减"政策的落地,属于K12教培机构的时代逐渐拉上帷幕,面对机会不再的K12教培行业,约70万机构和近千万的从业人员面临转型问题.压力之下,留下或离开?对广大K12教培机构从 ...

  7. 初学python-day3 元组

    day2 列表已更新!

  8. 配置 JAVA 环境 JDK + IDEA

    配置JDK 搜索 ORACLE 官网,找到 JDK,下载 JDK8 版本 / JDK11 版本 选择合适的路径,我这里放在了 D 盘 配置下方系统环境变量,变量名为 JAVA_HOME,把刚刚安装的J ...

  9. git常用的一些简单命令

    1.如果一个文件被修改了,但是还没有使用 git add 命令,此时想取消这次修改,需要执行的命令如下: git checkout -- 文件名 2.如果一个文件执行了 git add ,此时想取消这 ...

  10. [hi3521] nand flash 的 boot 启动模式的区别?

    spi nand flash 的 boot 启动模式选择.0:1 线 boot:1:4 线 boot.请问,1线boot和4线boot有什么区别呢?该如何选择呢?     收藏 顶 踩   回复 使用 ...