题目抽象:给你一个连通无向网,判断生成树是否唯一。
分析 :判定最小生成树是否唯一的一个正确思路为:
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 }