码迷,mamicode.com
首页 > 其他好文 > 详细

次小生成树

时间:2015-04-17 00:59:03      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

 

  次小生成树:所谓的次小生成树,是指在边集与某一最小生成树的边集不完全相同的其它生成树中值最小的那个。因此在数值上,最小生成树可能会等于次小生成树,这种情况也可以看做最小生成数。

  思路:最直观的解法是,首先求出最小生成树,并且记录最小生成树中的边,然后再枚举删除最小生成树的边并同时求最小生成树。

以POJ1679为例,Kruskal求次小生成树代码如下:

技术分享
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define _Clr(x, y) memset(x, y, sizeof(x))
  5 #define INF 0x3f3f3f3f
  6 #define N 110
  7 using namespace std;
  8 
  9 struct Edge
 10 {
 11     int a, b;
 12     int c;
 13     bool operator < (const Edge &a) const
 14     {
 15         return c < a.c;
 16     }
 17 }edge[N*N];
 18 int bleg[N], n, m;
 19 int mst_edge[N];
 20 
 21 int find(int x)
 22 {
 23     int y = x;
 24     while(y != bleg[y])
 25         y = bleg[y];
 26     while(x != bleg[x])
 27     {
 28         int px = bleg[x];
 29         bleg[x] = y;
 30         x = px;
 31     }
 32     return y;
 33 }
 34 
 35 void Union(int a, int b)
 36 {
 37     int pa=find(a), pb=find(b);
 38     if(pa != pb)
 39         bleg[pa] = pb;
 40 }
 41 
 42 inline void Init()
 43 {
 44     for(int i=0; i<=n; i++)
 45         bleg[i] = i;
 46 }
 47 
 48 void Kruskal()
 49 {
 50     int mst_1=0;
 51     Init();
 52     _Clr(mst_edge, 0);
 53     sort(edge, edge+m);
 54     int k=0;
 55     for(int i=0; i<m && k<n-1; i++)
 56     {
 57         int a=find(edge[i].a);
 58         int b=find(edge[i].b);
 59         if(a != b)
 60         {
 61             mst_edge[k] = i;
 62             Union(a, b);
 63             mst_1 += edge[i].c;
 64             k++;
 65         }
 66     }
 67     // 枚举删除最小生成树中所有边求MST
 68     for(int i=0; i<n-1; i++)
 69     {
 70         int mst_2=0, k=0;
 71         Init();
 72         for(int j=0; j<m && k<n-1; j++)
 73         {
 74             if(mst_edge[i] == j) continue;
 75             int a=find(edge[j].a);
 76             int b=find(edge[j].b);
 77             if(a != b)
 78             {
 79                 Union(a, b);
 80                 mst_2 += edge[j].c;
 81                 k++;
 82             }
 83         }
 84         if(mst_1==mst_2 && k==n-1)
 85         {
 86             puts("Not Unique!");
 87             return;
 88         }
 89     }
 90     printf("%d\n", mst_1);
 91 }
 92 
 93 int main()
 94 {
 95     int T;
 96     scanf("%d", &T);
 97     while(T--)
 98     {
 99         scanf("%d%d", &n, &m);
100         for(int i=0; i<m; i++)
101             scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].c);
102         Kruskal();
103     }
104     return 0;
105 }
View Code

 

次小生成树

标签:

原文地址:http://www.cnblogs.com/khan724/p/4433681.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!