[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],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的更多相关文章
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- 基于MST的立体匹配及相关改进(A Non-Local Cost Aggregation Method for Stereo Matching)
怀着很纠结的心情来总结这篇论文,这主要是因为作者提虽然供了源代码,但是我并没有仔细去深究他的code,只是把他的算法加进了自己的项目.希望以后有时间能把MST这一结构自己编程实现!! 论文题目是基于非 ...
- BZOJ 2654 & 玄学二分+MST
题意: 给一张图,边带权且带颜色黑白,求出一棵至少包含k条白边的MST SOL: 正常人都想优先加黑边或者是白边,我也是这么想的...你看先用白边搞一棵k条边的MST...然后维护比较黑边跟白边像堆一 ...
- LA 5713 秦始皇修路 MST
题目链接:http://vjudge.net/contest/144221#problem/A 题意: 秦朝有n个城市,需要修建一些道路使得任意两个城市之间都可以连通.道士徐福声称他可以用法术修路,不 ...
- [poj1679]The Unique MST(最小生成树)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28207 Accepted: 10073 ...
- [BZOJ2654]tree(二分+MST)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2654 分析:此题很奇葩,我们可以给所有白边加上一个权值mid,那么在求得的MST中白边 ...
- CodeForces 125E MST Company
E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...
- 2015baidu复赛2 连接的管道(mst && 优先队列prim)
连接的管道 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)
判别MST是否唯一的例题. POJ1679-The Unique MST 题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique! 题解:MST是否唯一取决于是否有 ...
随机推荐
- (Java)面向对象的三大特征
封装.继承与多态 封装 封装的作用(好处) 提高程序安全性,保护数据 隐藏代码的实现细节 统一接口 增加系统可维护性 属性私有(关键字private) 加上Private可使该属性私有于一个类,在其他 ...
- C#开发BIMFACE系列45 服务端API之创建离线数据包
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] BIMFACE的常规应用方式有公有云与私有化部署两种方式,并且浏览模型或者图纸需要使用ViewToken,ViewToke ...
- web全栈后台权限管理系统(VUE+ElementUi+nodeJs+koa2)
web全栈后台权限管理系统(VUE+ElementUi+nodeJs+koa2) 主要技术 前端 vue 全家桶 ElementUI 后端 Node.js Koa2 Mongoess 数据库 mong ...
- iNeuOS工业互联网操作系统,设备振动状态监测、预警和分析应用案例
目 录 1. 概述... 2 2. 系统部署结构... 2 3. 系统应用介绍... 4 4. 专业分析人员... 8 5. 应用案例分享 ...
- Ajax样例
$.ajax({ url : "newsservlet",//请求地址 dataType : "json",//数据格式 type : "post&q ...
- Linux Manual
man 命令用来访问存储在Linux系统上的手册页面.在想要查找的工具的名称前面输入man命 令,就可以找到那个工具相应的手册条目. 手册页不是唯一的参考资料.还有另一种叫作 info 页面的信息.可 ...
- python的函数参数传递方式
python的一切数据类型都是对象.但是python的对象分为不可变对象和可变对象.python的变量是引用,对python变量的赋值是引用去绑定该对象. 可变对象的数据发生改变,例如列表和字典,引用 ...
- java中的软,弱,虚引用介绍与特性分析
java的弱,虚,软引用介绍 1.弱,虚,软引用的介绍 对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会 ...
- 攻防世界 杂项13.can_has_stdio?
打开发现是由trainfuck编码组成的小星星阵容,果断交给解密网站进行解密, 解密网站:http://ctf.ssleye.com/brain.html flag:flag{esolangs_for ...
- 洛谷 P6075 [JSOI2015]子集选取
链接:P6075 前言: 虽然其他大佬们的走分界线的方法比我巧妙多了,但还是提供一种思路. 题意: %&¥--@#直接看题面理解罢. 分析过程: 看到这样的题面我脑里第一反应就是DP,但是看到 ...