判断最小生成树是否唯一的思路:
(1) 对图中每条边,扫描其它边,如果存在权值相同的边,则对该边作标记
(2) 然后用Kruskal算法求MST
(3) 求得MST后,如果该MST中为包含作了标记的边,即可判定MST唯一;
如果包含作了标记的边,则依次去掉这些边再求MST,如果求得的MST
权值与原MST的权值相同,即可判定MST不唯一
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 #define N 105 8 #define M 10050 9 struct Edge 10 { 11 int u,v,w; 12 int equal; 13 int del; 14 int used; 15 }edge[M]; 16 int father[N],rank[N]; 17 int n,m; 18 bool first; 19 20 bool cmp(Edge a,Edge b) 21 { 22 return a.w < b.w ; 23 } 24 25 void Init() 26 { 27 for(int i=1; i<=n; i++) 28 { 29 rank[i] = 1; 30 father[i] = i; 31 } 32 } 33 34 int find(int x) 35 { 36 if(father[x] != x) 37 father[x] = find(father[x]); 38 return father[x]; 39 } 40 41 void merge(int x,int y) 42 { 43 int xf = find(x); 44 int yf = find(y); 45 if(rank[xf] > rank[yf]) 46 { 47 rank[xf] += rank[yf]; 48 father[yf] = xf; 49 } 50 else 51 { 52 rank[yf] += rank[xf]; 53 father[xf] = yf; 54 } 55 } 56 57 int Kruskal() 58 { 59 int num = 0; 60 int sum = 0; 61 Init(); 62 for(int i=0; i<m; i++) 63 { 64 int u = edge[i].u ; 65 int v = edge[i].v ; 66 if(edge[i].del) continue; 67 if(find(u) != find(v)) 68 { 69 num++; 70 sum += edge[i].w; 71 merge(u,v); 72 if(first) edge[i].used = 1; 73 } 74 if(num==n-1) break; 75 } 76 if(num<n-1) return -1; 77 return sum; 78 } 79 80 int main() 81 { 82 int T; 83 int u,v,w; 84 scanf("%d",&T); 85 while(T--) 86 { 87 scanf("%d%d",&n,&m); 88 for(int i=0; i<m; i++) 89 { 90 scanf("%d%d%d",&u,&v,&w); 91 edge[i].u = u ; edge[i].v = v ; edge[i].w = w ; 92 edge[i].equal = 0 ; edge[i].del = 0 ; edge[i].used = 0 ; 93 } 94 for(int i=0; i<m; i++) 95 for(int j=i+1; j<m; j++) 96 { 97 if(edge[i].w == edge[j].w) 98 edge[i].equal = edge[j].equal = 1; 99 } 100 sort(edge,edge+m,cmp); 101 first = 1; 102 int sum1 = Kruskal(); 103 int flag = 1; 104 first = 0; 105 for(int i=0; i<m; i++) 106 { 107 if(edge[i].used && edge[i].equal) 108 { 109 edge[i].del = 1; 110 int sum2 = Kruskal(); 111 if(sum1 == sum2) 112 { 113 printf("Not Unique! "); 114 flag = 0; 115 break; 116 } 117 edge[i].del = 0; 118 } 119 } 120 if(flag) printf("%d ",sum1); 121 } 122 return 0; 123 }