标签:
题目链接:
http://poj.org/problem?id=1679
题目大意:
判断所给的n个节点,m条无向边,构成的无向图是否只存在唯一的最小生成树?
解题思路:
可以用prim求出最小生成树,再求次小生成树,两者进行比较即可。
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int maxn = 110; 9 const int INF = 0x3f3f3f3f; 10 11 int cost[maxn][maxn], vis[maxn], lowc[maxn]; 12 int pre[maxn], used[maxn][maxn], Max[maxn][maxn]; 13 //pre[i]为i在MST中的前驱,used记录边的使用情况,Max[i][j]表示在MST中i到j中最长的边 14 void init () 15 { 16 for (int i=0; i<maxn; i++) 17 for (int j=0; j<maxn; j++) 18 if (i == j) 19 cost[i][j] = 0; 20 else 21 cost[i][j] = INF; 22 } 23 int prim (int n) 24 { 25 int i, j, sum = 0; 26 memset (vis, 0, sizeof(vis)); 27 memset (Max, 0, sizeof(Max)); 28 memset (used, 0, sizeof(used)); 29 vis[1] = 1; 30 31 for (i=1; i<=n; i++) 32 { 33 pre[i] = 1; 34 lowc[i] = cost[1][i]; 35 } 36 37 for (i=1; i<n; i++) 38 { 39 int mini = INF; 40 int p; 41 for (j=1; j<=n; j++) 42 { 43 if (!vis[j] && mini > lowc[j]) 44 { 45 p = j; 46 mini = lowc[j]; 47 } 48 } 49 if (INF == mini) 50 return -1; 51 vis[p] = 1; 52 used[p][pre[p]] = used[pre[p]][p] = 1; 53 //记录边的使用情况 54 sum += mini; 55 for (j=1; j<=n; j++) 56 { 57 if (vis[j]) 58 Max[j][p] = max(Max[j][pre[p]], lowc[p]); 59 //如果j已经在MST中,则需要更新j到p的最长边 60 else if (lowc[j] > cost[p][j]) 61 { 62 lowc[j] = cost[p][j]; 63 pre[j] = p; 64 //如果加入最小花费优化成功,j就需要改变前驱 65 } 66 } 67 } 68 return sum; 69 } 70 int smst (int n, int ans) 71 { 72 int i, j, mini = INF; 73 for (i=1; i<=n; i++)//枚举所有的边 74 for (j=i+1; j<=n; j++) 75 if (cost[i][j] != INF && !used[i][j])//如果当前边没有被使用过,就用当前边代替最大权边 76 mini = min(mini, ans - cost[i][j] + Max[i][j]); 77 if (mini == INF) 78 return -1; 79 return mini; 80 } 81 int main () 82 { 83 int t, n, m; 84 scanf ("%d", &t); 85 while (t --) 86 { 87 scanf ("%d %d", &n, &m); 88 init (); 89 while (m --) 90 { 91 int x, y, w; 92 scanf ("%d %d %d", &x, &y, &w); 93 cost[x][y] = cost[y][x] = w; 94 } 95 int num1, num2; 96 num1 = prim(n); 97 if (num1 != -1) 98 num2 = smst (n, num1); 99 100 if (num1 == num2)//最小生成树与次小生成树相同 101 printf ("Not Unique!\n"); 102 else 103 printf ("%d\n", num1); 104 } 105 return 0; 106 }
poj 1679 The Unique MST (次小生成树)
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4546511.html