题目链接:http://poj.org/problem?id=1679
给你一个图的连通情况,询问你此图的最小生成树是否唯一。
假如最小生成树唯一,即生成树连通所有节点的权值和唯一。假如不唯一,那么存在另一条最小生成树使得权值等于之前最小生成树的权值。
换个思路考虑,也就是次小生成树的权值与最小生成树的权值相同,那么问题就变成了求次小生成树的权值。
我选择的是先求出最小生成树,将树上用到的边都保存下来。接着分别将每一条用到的边摘下来,再求一次最小生成树。假如不包含当前删掉的边生成的生成树的所选边权值与最小生成树的所选边权值相同,那么最小生成树就是不唯一的了。
代码:
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef struct Node { 23 int u; 24 int v; 25 int w; 26 }Node; 27 28 bool cmp(Node n1, Node n2) { 29 return n1.w < n2.w; 30 } 31 32 const int maxn = 111; 33 Node node[6666]; 34 int vis[maxn]; 35 int n, m, u, v, w; 36 int pre[maxn]; 37 int cnt, dig, flag, ans; 38 39 void init() { 40 for(int i = 0; i <= maxn; i++) { 41 pre[i] = i; 42 } 43 } 44 45 int find(int x) { 46 return x == pre[x] ? x : pre[x] = find(pre[x]); 47 } 48 49 void unite(int x, int y) { 50 x = find(x); 51 y = find(y); 52 if(x != y) pre[y] = x; 53 } 54 55 int main() { 56 // freopen("in", "r", stdin); 57 int T; 58 scanf("%d", &T); 59 while(T--) { 60 init(); 61 memset(vis, 0, sizeof(vis)); 62 memset(node, 0, sizeof(node)); 63 dig = 0; 64 cnt = 0; 65 flag = 0; 66 scanf("%d %d", &n, &m); 67 for(int i = 0; i < m; i++) { 68 scanf("%d %d %d", &u, &v, &w); 69 node[i].u = u; 70 node[i].v = v; 71 node[i].w = w; 72 } 73 sort(node, node+m, cmp); 74 for(int i = 0; i < m && cnt < n; i++) { 75 if(find(node[i].u) != find(node[i].v)) { 76 unite(node[i].u, node[i].v); 77 vis[cnt++] = i; 78 dig += node[i].w; 79 } 80 } 81 ans = dig; 82 83 for(int i = 1; i < n; i++) { 84 init(); 85 cnt = n - 1; 86 dig = 0; 87 for(int j = 0; j < m && cnt; j++) { 88 if(vis[i] != j && find(node[j].u) != find(node[j].v)) { 89 unite(node[j].u, node[j].v); 90 dig += node[j].w; 91 cnt--; 92 } 93 } 94 if(cnt == 0 && dig == ans) { 95 flag = 1; 96 break; 97 } 98 } 99 100 if(flag) printf("Not Unique!\n"); 101 else printf("%d\n", ans); 102 } 103 }
时间: 2024-10-10 17:19:30