POJ 1679 The Unique MST (次小生成树)

题目链接:http://poj.org/problem?id=1679

有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树)。

 

先求出最小生成树的大小,把最小生成树的边存起来。然后分别枚举最小生成树上的每条边,除了这条边,其他边是否能生成最小生成树,若生成树的权值等于原来最小生成树的权值,则不唯一,否则输出最小生成树的权值。这里我用kruskal比较方便。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 const int MAXN = 105;
 8 const int INF = 1e9;
 9 struct edge {
10     int u , v , cost;
11 }a[MAXN * MAXN];
12 typedef pair <int , int> P;
13 int par[MAXN] , f;
14 bool vis[MAXN][MAXN];
15 vector <P> G;
16 
17 void init(int n) {
18     for(int i = 1 ; i <= n ; i++) {
19         par[i] = i;
20     }
21     memset(vis , false , sizeof(vis));
22     f = 0;
23     G.clear();
24 }
25 
26 bool cmp(edge a , edge b) {
27     return a.cost < b.cost;
28 }
29 
30 int Find(int n) {
31     if(par[n] == n)
32         return n;
33     return (par[n] = Find(par[n]));
34 }
35 
36 int kruskal(int m , int n) {
37     int res = 0 , cont = n;
38     for(int i = 1 ; i <= m ; i++) {
39         if(cont == 1)
40             break;
41         else if(vis[a[i].u][a[i].v])
42             continue;
43         int u = Find(a[i].u) , v = Find(a[i].v);
44         if(u != v) {
45             if(!f) {
46                 G.push_back(P(a[i].u , a[i].v)); // f等于0的时候是求最小生成树的时候,存边操作
47             }
48             par[u] = v;
49             res += a[i].cost;
50             cont--;
51         }
52     }
53     if(cont == 1)
54         return res;
55     return INF;
56 }
57 
58 int main()
59 {
60     int t , n , m , u , v , w;
61     scanf("%d" , &t);
62     while(t--) {
63         scanf("%d %d" , &n , &m);
64         init(n);
65         for(int i = 1 ; i <= m ; i++) {
66             scanf("%d %d %d" , &u , &v , &w);
67             a[i].u = u , a[i].v = v , a[i].cost = w;
68         }
69         sort(a + 1 , a + m + 1 , cmp);
70         int res = kruskal(m , n) , check = 0;
71         f++;
72         for(int i = 0 ; i < G.size() ; i++) {
73             for(int j = 1 ; j <= n ; j++) {
74                 par[j] = j;
75             }
76             vis[G[i].first][G[i].second] = true;
77             if(res == kruskal(m , n)) {
78                 check = 1;
79                 break;
80             }
81             vis[G[i].first][G[i].second] = false;
82         }
83         if(check) {
84             printf("Not Unique!\n");
85         }
86         else {
87             printf("%d\n" , res);
88         }
89     }
90 }

 

posted @ 2016-03-22 23:18  Recoder  阅读(107)  评论(0编辑  收藏  举报