次小生成树是指在一个树中除最小生成树外第二小的生成树,因此它是在最小生成树算法上衍生的。首先在求出最小生成树后,假如我们要加上一条树外的边,这样就会形成一个闭环,然后将这个闭环的最大
的边删除,那么剩下的依然是一个树,如果这个树<=最小生成树,那么它就是次小生成树。
如果我们要加边的话,加的肯定是树外的边,这个用一个标记数组就行,然后我们还要找闭环的最大边值,
1。secondprim算法
2.Second_Kruskal算法
1 struct node 2 { 3 //x,y表示边的左右端点,value表示边的值 4 int x,y,value; 5 //flag标记边是否在树上 6 bool flag; 7 }no[205]; 8 //n表示点数,m表示边数 9 int n,m; 10 //fa表示树上的顶点 11 int fa[105]; 12 //ve用于与第i个点有连接的点 13 vector<int> ve[105]; 14 //maxn存放两点之间的最大值 15 int maxn[105][105]; 16 //初始化 17 void init() 18 { 19 //开始时与自己相连的只有自己,同时顶点也是自己 20 for(int i=0;i<=n;i++) 21 { 22 ve[i].clear(); 23 ve[i].push_back(i); 24 fa[i]=i; 25 } 26 } 27 //查找顶点 28 int find(int x) 29 { 30 //如果找到顶点,则返回 31 if(fa[x]==x) 32 { 33 return x; 34 } 35 //递归查找x的上一个点的上一个点,同时压缩路径 36 return fa[x]=find(fa[x]); 37 } 38 //排序,按边的值从小到大 39 bool cmp(node a,node b) 40 { 41 return a.value<b.value; 42 } 43 //最小生成树Kruskal算法 44 int kruskal() 45 { 46 //对边进行排序 47 sort(no+1,no+m+1,cmp); 48 //初始化数据 49 init(); 50 //ans表示最小生成树的权值和,cnt表示已经连接的边数 51 int ans=0,cnt=0; 52 //遍历所有边 53 for(int i=1;i<=m;i++) 54 { 55 //如果连接了n-1个边,则表示已经连接所有的点了 56 if(cnt==n-1) 57 { 58 break; 59 } 60 //记录当前边的两边端点的顶点 61 int fx=find(no[i].x),fy=find(no[i].y); 62 //如果他们不相等则进行操作 63 if(fx!=fy) 64 { 65 //将fx的顶点变成fy,相当于把fx这个树的顶点挂在fy这个树顶的下面 66 fa[fx]=fy; 67 //生成树的边数加1 68 cnt++; 69 //加上这个边的权值 70 ans+=no[i].value; 71 //标记这个边 72 no[i].flag=true; 73 //对fx,fy则两颗树的所有点遍历 74 for(int j=0;j<ve[fx].size();j++) 75 { 76 for(int k=0;k<ve[fy].size();k++) 77 { 78 //将这两可树的所有点之间的最大值都变成现在变的值 79 //由于对no进行过排序,因此此时no[i].value的值是这个树上的最大值 80 maxn[ve[fx][j]][ve[fy][k]]=maxn[ve[fy][k]][ve[fx][j]]=no[i].value; 81 } 82 } 83 //对fx的树遍历,将fx树上的点都连在fy树上 84 for(int j=0;j<ve[fx].size();j++) 85 { 86 ve[fy].push_back(ve[fx][j]); 87 } 88 } 89 } 90 //如果连了n-1条边则表示有最小生成树 91 if(cnt==n-1) 92 { 93 return ans; 94 } 95 else 96 { 97 return -1; 98 } 99 } 100 //次小生成树,mst表示最小生成树的权值和 101 int second_kruskal(int mst) 102 { 103 int ans=INF; 104 //遍历所有边 105 for(int i=1;i<=m;i++) 106 { 107 //如果这个边不在最小生成树上 108 if(!no[i].flag) 109 { 110 //计算最小生成树加外边在减内边否的最小值 111 ans=min(ans,mst+no[i].value-maxn[no[i].x][no[i].y]); 112 } 113 } 114 return ans; 115 }