The Unique MST 判断生成树是否唯一

                          The Unique MST

题目抽象:给你一个连通无向网,判断生成树是否唯一。

分析 :判定最小生成树是否唯一的一个正确思路为:

1) 对图中每条边,扫描其他边,如果存在相同权值的边,则对该边作标记;
2) 然后用 Kruskal 算法(或 Prim 算法)求 MST;
3) 求得 MST 后,如果该 MST 中未包含作了标记的边,即可判定 MST 唯一;如果包含作了
标记的边,则依次去掉这些边再求 MST,如果求得的 MST 权值和原 MST 的权值相同,即可判定
MST 不唯一。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <string>
  7 #include <vector>
  8 #include <set>
  9 #include <map>
 10 #include <queue>
 11 #include <stack>
 12 #include <cstdlib>
 13 #include <sstream>
 14 using namespace std;
 15 typedef long long LL;
 16 const LL INF = 0x5fffffff;
 17 const double EXP = 1E-6;
 18 const LL MOD = (LL)1E9+7;
 19 const int MS = 105;
 20 
 21 struct edge {
 22     int u, v, w;
 23     int equal, used, del;
 24     bool operator < (const edge & a) {
 25         return w < a.w;
 26     }
 27 }edges[MS * MS / 2];
 28 
 29 int fa[MS];
 30 int n, m, first;
 31 
 32 int find(int x) {
 33     int s = x;
 34     while (fa[s] >= 0)
 35         s = fa[s];
 36     while (s != x) {
 37         int t = fa[x];
 38         fa[x] = s;
 39         x = t;
 40     }
 41     return s;
 42 }
 43 
 44 void merge(int x, int y) {
 45     int fx = find(x);
 46     int fy = find(y);
 47     int t = fa[fx] + fa[fy];
 48     if (fa[fx] > fa[fy]) {
 49         fa[fx] = fy;
 50         fa[fy] = t;
 51     }
 52     else {
 53         fa[fy] = fx;
 54         fa[fx] = t;
 55     }
 56 }
 57 
 58 int MST() {
 59     memset(fa,-1,sizeof(fa));
 60     int sum = 0;
 61     int c = 0;
 62     for (int i = 0; i < m; i++) {
 63         if (edges[i].del)
 64             continue;
 65         int u = edges[i].u;
 66         int v = edges[i].v;
 67         if (find(u) != find(v)) {
 68             sum += edges[i].w;
 69             c++;
 70             merge(u, v);
 71             if (first)
 72                 edges[i].used = 1;
 73         }
 74         if (c >= n - 1)
 75             break;
 76     }
 77     return sum;
 78 }
 79 
 80 int main() {
 81     int T, u, v, w;
 82     scanf("%d",&T);
 83     while (T--) {
 84         scanf("%d%d", &n, &m);
 85         for (int i = 0; i < m; i++) {
 86             scanf("%d%d%d", &u, &v, &w);
 87             edges[i].u = u - 1;
 88             edges[i].v = v - 1;
 89             edges[i].w = w;
 90             edges[i].equal = 0;
 91             edges[i].used = 0;
 92             edges[i].del = 0;
 93         }
 94         for (int i = 0; i < m; i++)
 95             for (int j = i +1; j < m; j++)
 96                 if (edges[i].w == edges[j].w)
 97                     edges[i].equal = edges[j].equal = 1;
 98         sort(edges, edges + m);
 99         first = 1;
100         int ans = MST();
101         first = 0;
102         int flag = 1;
103         for (int i = 0; i < m; i++) {
104             if (edges[i].used && edges[i].equal) {
105                 edges[i].del = 1;
106                 int t = MST();
107                 if (t == ans) {
108                     printf("Not Unique!\n");
109                     flag = 0;
110                     break;
111                 }
112                 edges[i].del = 0;
113             }
114         }
115         if (flag)
116             printf("%d\n",ans);
117     }
118     return 0;
119 }

 

posted on 2015-08-19 20:56  hutaishi  阅读(374)  评论(0编辑  收藏  举报

导航