题目链接:http://poj.org/problem?id=1679
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 29408 | Accepted: 10520 |
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
题目大意: 给定一个连通无向网,判定它的最小生成树是否唯一。
解题思路: http://www.cnblogs.com/yoke/p/6527300.html
AC代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct point 8 { 9 int u,v,w; 10 int equal; // 标记,1表示存在其他边权值跟该边一样,0表示不存在 11 int used; // 在第一次求得的MST中,是否包含该边,1包含,0不包含 12 int del; // 边是否删除 0不删除 1删除 13 }p[10000]; // 存边的数组 14 int n,m; 15 int first; // 表示第一次求MST的标记变量 16 int parent[110]; 17 bool cmp(point a, point b) 18 { 19 return a.w < b.w; 20 } 21 int find (int x) 22 { 23 int s,tmp; 24 for (s = x; parent[s] >= 0; s = parent[s]); 25 while (s != x) 26 { 27 tmp = parent[x]; 28 parent[x] = s; 29 x = tmp; 30 } 31 return s; 32 } 33 void Union (int A, int B) 34 { 35 int a = find(A), b = find(B); 36 int tmp = parent[a]+parent[b]; 37 if (parent[a] > parent[b]) 38 { 39 parent[a] = b; 40 parent[b] = tmp; 41 } 42 else 43 { 44 parent[b] = a; 45 parent[a] = tmp; 46 } 47 } 48 int kruskal() 49 { 50 int sum = 0,num = 0; 51 memset(parent,-1,sizeof(parent)); 52 for (int i = 0; i < m; i ++) 53 { 54 if (p[i].del) continue; // 忽略去掉的边 55 int u = p[i].u, v = p[i].v; 56 if (find(u) != find(v)) 57 { 58 if (first) p[i].used = 1; 59 sum += p[i].w; 60 Union(u,v); 61 num ++; 62 } 63 if (num == n-1) break; 64 } 65 return sum; 66 } 67 int main () 68 { 69 int t,i,j,u,v,w; 70 scanf("%d",&t); 71 while (t --) 72 { 73 scanf("%d%d",&n,&m); 74 for (i = 0; i < m; i ++) 75 { 76 scanf("%d%d%d",&u,&v,&w); 77 p[i].u = u; p[i].v = v; p[i].w = w; 78 p[i].equal = 0; p[i].used = 0; p[i].del = 0; 79 } 80 for (i = 0; i < m; i ++) // 标记相同权值的边 81 for (j = i+1; j < m; j ++) 82 if (p[i].w == p[j].w) 83 p[i].equal = 1; 84 first = 1; 85 sort(p,p+m,cmp); 86 int sum = kruskal(), sum1; // 第一次求MST 87 first = 0; 88 for (i = 0; i < m; i ++) 89 { 90 if (p[i].equal && p[i].used) // 依次去掉原MST中相同权值的边 91 { 92 p[i].del = 1; 93 sum1 = kruskal(); 94 if (sum == sum1) 95 { 96 printf("Not Unique!\n"); 97 break; 98 } 99 p[i].del = 0; 100 } 101 } 102 if (i == m) 103 printf("%d\n",sum); 104 } 105 return 0; 106 }
poj 1679 The Unique MST (判定最小生成树是否唯一)
原文:http://www.cnblogs.com/yoke/p/6527292.html