【题意】:问图中的最小生成树是否唯一。

【题解】:先求出最小生成树,再求次小生成树,如果最小生成树 == 次小生成树,则不唯一;否则,唯一。纯粹模板题。

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 using namespace std;
11 #define pb push_back
12 #define lc(x) (x << 1)
13 #define rc(x) (x << 1 | 1)
14 #define lowbit(x) (x & (-x))
15 #define ll long long
16 const int inf = 1 << 30;
17 #define maxn 150
18 int maz[maxn][maxn], path[maxn][maxn];
19 bool visit[maxn];
20 int dist[maxn], pre[maxn], stack[maxn];
21 int n, m;
22 
23 void init() {
24     for (int i = 1; i <= n; i++) 
25         for (int j = 1; j <= n; j++) 
26             maz[i][j] = inf, path[i][j] = 0;
27 }
28 
29 int Prim(int s) {
30     for (int i = 1; i <= n; i++) dist[i] = maz[s][i], visit[i] = 0, pre[i] = s;
31     int top = 0, sum = 0;
32     visit[s] = true, dist[s] = 0, stack[top++] = s;
33     while (1) {
34         int u = -1;
35         for (int i = 1; i <= n; i++)
36             if (!visit[i] && (u == -1 || dist[u] > dist[i]))
37                 u = i;
38         if (u == -1) break;
39         sum += dist[u], stack[top++] = u, visit[u] = true;
40         for (int i = 0; i < top; i++) {
41             if (stack[i] == u) continue;
42             path[stack[i]][u] = max(path[pre[u]][stack[i]], dist[u]);
43             path[u][stack[i]] = path[stack[i]][u];
44         }
45         for (int i = 1; i <= n; i++)
46             if (!visit[i] && (maz[u][i] < dist[i]))
47                 dist[i] = maz[u][i], pre[i] = u;
48     }
49     return sum;
50 }
51 
52 void SMT() {//次小生成树
53     int Min = inf, sum = Prim(1);//先求一次最小生成树
54     for (int i = 1; i < n; i++)
55         for (int j = i + 1; j <= n; j++)
56             if (pre[i] != j && pre[j] != i && maz[i][j] < inf)
57                 Min = min(Min, sum - path[i][j] + maz[i][j]);
58     if (Min == sum) puts("Not Unique!");
59     else printf("%d\n", sum);
60 }
61 
62 int main() {
63     int T, u, v, w;
64     scanf("%d", &T);
65     while(T--) {
66         scanf("%d%d", &n, &m);
67         init();
68         for(int i = 0; i < m; i++) {
69             scanf("%d%d%d", &u, &v, &w);
70             maz[u][v] = maz[v][u] = w;
71         }
72         SMT();
73     }
74     return 0;
75 }