次小生成树
Posted tingtin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了次小生成树相关的知识,希望对你有一定的参考价值。
1 /* 2 最小生成树唯一吗,求出次小生成树 3 枚举每个非最小生成树里面的边, 4 加上该边后一定会形成环 5 最小生成树+该边-最小生成树在环中的最长边 6 */ 7 /* 8 #include <cstdio> 9 #include <iostream> 10 #include <algorithm> 11 #include <cstring> 12 #include <vector> 13 using namespace std; 14 #define ph push_back 15 const int inf =0x3f3f3f3f; 16 const int N =150; 17 #define ph push_back 18 int pre[N],maxx[N][N]; 19 vector<int>ve[N]; 20 int t,n,m; 21 struct Edge{ 22 int from,to,w; 23 bool vis; 24 }e[N*N*2]; 25 bool cmp(Edge a,Edge b){ 26 return a.w<b.w; 27 } 28 int find(int x){ 29 return pre[x] = pre[x]==x?x:find(pre[x]); 30 } 31 void krusal(){ 32 for(int i =0;i<=n;i++){ 33 pre[i]=i; 34 ve[i].clear(); 35 ve[i].ph(i); 36 37 } 38 sort(e,e+m,cmp); 39 int sum=0,cnt=n; 40 for(int i=0;i<m;i++){ 41 if(cnt>1){ 42 int x =find(e[i].from),y=find(e[i].to); 43 if(x!=y){ 44 cnt--; 45 e[i].vis=1; 46 sum+=e[i].w; 47 int l1=ve[x].size(),l2=ve[y].size(); 48 for(int j=0;j<l1;j++){ 49 for(int k =0;k<l2;k++){ 50 maxx[ve[x][j]][ve[y][k]] =maxx[ve[y][k]][ve[x][j]]=e[i].w; 51 //得到任意两个点之间,在最小生成树中的最长边 52 } 53 } 54 pre[x] =y; 55 int temp[N]; 56 for(int j=0;j<l2;j++){ 57 temp[j]=ve[y][j]; 58 } 59 for(int j=0;j<l1;j++){ 60 ve[y].ph(ve[x][j]); 61 } 62 for(int j=0;j<l2;j++){ 63 ve[x].ph(temp[j]); 64 } 65 } 66 } 67 } 68 int minn=inf; 69 for(int i=0;i<m;i++){ 70 if(!e[i].vis){ 71 minn=min(minn,sum+e[i].w-maxx[e[i].from][e[i].to]); 72 73 } 74 } 75 if(minn>sum){ 76 printf("%d ",sum); 77 } 78 else{ 79 printf("Not Unique! "); 80 } 81 } 82 int main() 83 { 84 scanf("%d",&t); 85 while(t--){ 86 scanf("%d%d",&n,&m); 87 for(int i =0;i<m;i++){ 88 scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w); 89 e[i].vis=0; 90 } 91 krusal(); 92 } 93 return 0; 94 } 95 */
以上是关于次小生成树的主要内容,如果未能解决你的问题,请参考以下文章