题意:若第二小生成树代价与最小生成树代价相等输出Not Unique!,否则输出最小代价;
对最小生成树的每一边标记后重新计算不含这条边的最小生成树,若代价与 MST 的相等说明有多种方案,复杂度为O(N^3)。
# include <stdio.h> # include <string.h> # define N 20005 typedef struct { int u, v, w; } Road; char f[N], use[N]; int n, m, p[205]; Road r[N]; int cmp(const void *x, const void *y) { return (*(Road*)x).w>(*(Road*)y).w ? 1:-1; } int find(int x) { return x==p[x] ? x:(p[x] = find(p[x])); } int main() { int i, ans, ok; while (~scanf("%d%d", &n, &m)) { for (i = 1; i <= m; ++i) scanf("%d%d%d",&r[i].u, &r[i].v, &r[i].w); qsort(r+1, m, sizeof(Road), cmp); memset(f, 0, sizeof(f)); memset(use, 0, sizeof(use)); ok = 0; ans = kruskal(1); if (ans > 0) { for (i = 1; i <= m; ++i) if (use[i]) { f[i] = 1; if (ans == kruskal(0)) { ok = 1; break; } f[i] = 0; } } else ok = 1; if (ok) puts("Not Unique!"); else printf("%d\n", ans); } return 0; } int kruskal(int min) { int i, ans, x, y, cnt; for (i = 1; i <= n; ++i) p[i] = i; cnt = ans = 0; for (i = 1; i <= m; ++i) if (!f[i]) { x = find(r[i].u); y = find(r[i].v); if (x != y) { p[x] = y; ans += r[i].w; ++cnt; if (min) use[i] = 1; /* 调试了很久,就是这句话写在了外面 */ } } return cnt==n-1 ? ans:-1; }