题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=24534#problem/C
题目大意:
判断最小生成树是否唯一。
题目思路:
对于如果有一条边A在最小生成树里面,并且存在和这条边权值一样的另外一条边B,那么再次求最小生成树的时候,把A去掉,看看求出的最小生成树是不是和原来的最小生成树权值一样。如果一样,就是不唯一,否则就刚才去掉的加进来,然后再找下一条这样的边。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 #define MAXN 110 8 #define MAXM 5009 9 typedef struct edge { 10 int u, v, w, used, del, equal; 11 bool operator < (const edge &other) const { 12 return w < other.w; 13 } 14 }edge; 15 edge edges[MAXM]; 16 int parent[MAXN]; 17 bool first; 18 int n, m, i, j; 19 void init() { 20 for (i = 1; i <= n; ++i) parent[i] = -1; 21 } 22 int find(int x) { 23 int s; 24 for (s = x; parent[s] >= 0; s = parent[s]) ; 25 while (s != x) { 26 int tmp = parent[x]; 27 parent[x] = s; 28 x = tmp; 29 } 30 return s; 31 } 32 void Union(int R1, int R2) { 33 int r1 = find(R1), r2 = find(R2), tmp = parent[r1] + parent[r2]; 34 if (parent[r1] > parent[r2]) { 35 parent[r1] = r2; parent[r2] = tmp; 36 } else { 37 parent[r2] = r1; parent[r1] = tmp; 38 } 39 } 40 int kruscal() { 41 int sum = 0, num = 0, u, v; 42 init(); 43 for (i = 1; i <= m; ++i) { 44 if (edges[i].del == 1) continue; 45 u = edges[i].u; v = edges[i].v; 46 if (find(u) != find(v)) { 47 sum += edges[i].w; num++; 48 Union(u, v); 49 if (first) edges[i].used = 1; 50 } 51 if (num >= n-1) break; 52 } 53 return sum; 54 } 55 int ma[MAXN][MAXN]; 56 int main(void) { 57 #ifndef ONLINE_JUDGE 58 freopen("hust_c.in", "r", stdin); 59 #endif 60 int t; scanf("%d", &t); 61 while (t--){ 62 int u, v, w; 63 scanf("%d%d", &n, &m); 64 for (i = 1; i<= m; ++i) { 65 scanf("%d%d%d", &u, &v, &w); 66 edges[i].u = u; edges[i].v = v; edges[i].w = w; 67 edges[i].del = 0; edges[i].used = 0; edges[i].equal = 0; 68 } 69 for (i = 1; i <= m; ++i) { 70 for (j = 1; j <= m; ++j) { 71 if (i == j) continue; 72 if (edges[i].w == edges[j].w) edges[i].equal = 1; 73 } 74 } 75 sort(edges, edges+m); 76 first = true; 77 int w1 = kruscal(), w2; 78 for (i = 1; i<=m; ++i) { 79 if (edges[i].used && edges[i].equal) { 80 edges[i].del = 1; 81 w2 = kruscal(); 82 if (w1 == w2) { 83 printf("Not Unique!\n"); break; 84 } 85 edges[i].del = 0; 86 } 87 } 88 if (i > m) printf("%d\n", w1); 89 } 90 91 return 0; 92 }
这题以前做过,模板题……