次小生成树
来源:互联网 发布:淘宝热卖排行榜 编辑:程序博客网 时间:2024/05/21 09:39
O(V^2)
结论
次小生成树可由最小生成树转换一条边得到
证明
T是某一棵最小生成树,T0是任一棵异于T的树,通过变换T0->T1->T2->…->Tn(T)变成最小生成树,所谓的变换是,每次把T_i中的某条边换成T中的一条边,而且树T_(i + 1)的权小于等于T_i的权。
具体操作是:
step1. 在T_i中任取一条不在T中的边u_V;
step2. 把边u_v去掉,就剩下两个连通分量A和B,在T中,必有唯一的边u’_v’连结A和B;
step3. 显然u’v’的权比u_v小(否则,u_v就应该在T中),把u’_v’替换u_v即得到树T(i + 1);
特别地:取Tn为任一棵次小生成树,T_(n - 1)也就是次小生成树且跟T差一条边,结论得证。
算法
只要充分利用上述结论,既得v^2的算法。具体如下:
step1. 先用Prim求出最小生成树T,在Prim的同时,用一个矩阵MAX[u][v]记录在T中连结任意两点u,v的唯一的路中权值最大的那条边的权值。(注意这里),这是很容易做到的,因为Prim是每次增加一个结点s,而已经标好了的结点集合为w,则w中所有的结点到s的路中最大权值的边就是当前加入的这条边,用时O(V^2);
step2.枚举所有不在T中的边u_v,加入边u_v替换权为MAX[u][v]的边,不断更新最小值,即次小生成树,用时O(E),故总用时O(V^2)。
代码C++
/* * 求最小生成树时,用数组MAX[i][j]表示i到j的最大边权 * 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案 * 点的编号从0开始 */const int MAXN = 110;const int INF = 0x3f3f3f3f;bool vis[MAXN];int lowc[MAXN];int pre[MAXN];int MAX[MAXN][MAXN];bool used[MAXN][MAXN];int Prim(int cost[][MAXN], int n){ int ans = 0; memset(vis, false, sizeof(vis)); memset(MAX, 0, sizeof(MAX)); memset(used, false, sizeof(used)); vis[0] = true; pre[0] = -1; lowc[0] = 0; for (int i = 1; i < n; i++) { lowc[i] = cost[0][i]; pre[i] = 0; } for (int i = 1; i < n; i++) { int minc = INF; int p = -1; for (int j = 0; j < n; j++) { if (!vis[j] && minc > lowc[j]) { minc = lowc[j]; p = j; } } if (minc == INF) { return -1; } ans += minc; vis[p] = true; used[p][pre[p]] = used[pre[p]][p] = true; for (int j = 0; j < n; j++) { if (vis[j]) { MAX[j][p] = MAX[p][j] = max(MAX[j][pre[p]], lowc[p]); } if (!vis[j] && lowc[j] > cost[p][j]) { lowc[j] = cost[p][j]; pre[j] = p; } } } return ans;}
1 0
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- 次小生成树
- tsliib分析
- 学习:基于Google的TensorFlow框架来介绍深度学习
- 哈密顿绕行世界问题
- 76-抽象 unix 域套接字地址
- RTMP 抓包分析
- 次小生成树
- iOS 程序从开发完到上 AppStore 那点事儿
- windows配置openvc3.2.0,java版,python版,C++visual stdio2017版
- C语言指针变量的运算
- 七牛云图片上传:使用element-ui的upload组件
- code[vs] 1039数的划分
- rtmp协议简单解析以及用其发送h264的flv文件
- 读懂tomact源码4:Container
- Linux简单命令