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

我写了个暴力的算法,先求一遍最小生成树。然后枚举所有最小生成树的边依次删除,每次再计算一次最小生成树,取最小值,然后和一开始求的值比较。原理是次小生成树的边一定至少有一条和最小生成树的不一样。
注意:删除一条边之后图可能不连通,不连通的图没有生成树,应该返回最大值。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #define maxn 10005
 5 struct edge{
 6     int u, v, c, p;
 7 }g[maxn];
 8 int par[maxn], n, m;
 9 int find(int x){return par[x] < 0 ? x : par[x] = find(par[x]);}
10 bool comp(const edge &a, const edge &b){return a.c < b.c;}
11 int mst()
12 {
13     memset(par, -1, sizeof(par));
14     int ans = 0;
15     for (int i = 0; i < m; ++i){
16         if (g[i].p == 2) continue;
17         int x = find(g[i].u), y = find(g[i].v);
18         if (x != y){
19             ans += g[i].c;
20             par[x] += par[y];
21             par[y] = x;
22         }
23     }
24     if (-par[find(g[0].u)] != n) return 0x3f3f3f3f;
25     else return ans;
26 }
27 int main()
28 {
29     int t;
30     scanf("%d", &t);
31     while (t--){
32         scanf("%d %d", &n, &m);
33         for (int i = 0; i < m; ++i) scanf("%d %d %d", &g[i].u, &g[i].v, &g[i].c);
34         std::sort(g, g + m, comp);
35         int ans = 0;
36         memset(par, -1, sizeof(par));
37         for (int i = 0; i < m; ++i){
38             int x = find(g[i].u), y = find(g[i].v);
39             if (x != y){
40                 g[i].p = 1;
41                 ans += g[i].c;
42                 par[x] += par[y];
43                 par[y] = x;
44             }
45         }
46         if (-par[find(g[0].u)] != n) puts("Not Unique!");
47         else{
48             int tans = 0x3f3f3f3f;
49             for (int i = 0; i < m; ++i){
50                 if (g[i].p == 1){
51                     g[i].p = 2;
52                     tans = std::min(tans, mst());
53                     g[i].p = 0;
54                 }
55             }
56             if (ans == tans) puts("Not Unique!");
57             else printf("%d\n", ans);
58         }
59     }
60     return 0;
61 }

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄