题目大意:
给n个节点,m条边,问最小生成树,次小生成树?
ps:以前做次小生成树的时候估计没有掌握牢固,这次wa的好辛苦哟。
1 #include <cmath> 2 #include <queue> 3 #include <string> 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 const int maxn = 100; 11 const int INF = 0x3f3f3f3f; 12 const double Exp = 1e-10; 13 14 int cost[maxn+10][maxn+10], lowc[maxn+10], vis[maxn+10]; 15 int Max[maxn+10][maxn+10], used[maxn+10][maxn+10], pre[maxn+10]; 16 int n; 17 void init () 18 { 19 for (int i=1; i<=n; i++) 20 for (int j=1; j<=n; j++) 21 if (i == j) 22 cost[i][j] = 0; 23 else 24 cost[i][j] = INF; 25 } 26 int prim () 27 { 28 int i, j, sum = 0; 29 memset (Max, 0, sizeof(Max)); 30 memset (used, 0, sizeof(used)); 31 memset (vis, 0, sizeof(vis)); 32 vis[1] = 1; 33 for (i=1; i<=n; i++) 34 { 35 lowc[i] = cost[1][i]; 36 pre[i] = 1; 37 } 38 for (i=1; i<n; i++) 39 { 40 int p, mini = INF; 41 for (j=1; j<=n; j++) 42 if (!vis[j] && mini > lowc[j]) 43 { 44 p = j; 45 mini = lowc[j]; 46 } 47 vis[p] = 1; 48 sum += mini; 49 used[pre[p]][p] = used[p][pre[p]] = 1; 50 for (j=1; j<=n; j++) 51 {//这一点的错误wa的好苦 52 if (vis[j] && j != p)//p!=j一定要有,否则Max[i][i]的距离就可能会不等于零,影响后面的计算过程 53 Max[j][p] = Max[p][j] = max(Max[j][pre[p]], lowc[p]); 54 if (!vis[j] && lowc[j] > cost[p][j]) 55 { 56 lowc[j] = cost[p][j]; 57 pre[j] = p; 58 } 59 } 60 } 61 return sum; 62 } 63 int smst (int sum) 64 { 65 int i, j, mini = INF; 66 for (i=1; i<=n; i++) 67 for (j=i+1; j<=n; j++) 68 if (cost[i][j] != INF && !used[i][j]) 69 mini = min (mini, sum + cost[i][j] - Max[i][j]); 70 return mini; 71 } 72 int main () 73 { 74 int t, m; 75 scanf ("%d", &t); 76 while (t --) 77 { 78 scanf ("%d %d", &n, &m); 79 init (); 80 while (m --) 81 { 82 int a, b, c; 83 scanf ("%d %d %d", &a, &b, &c); 84 cost[a][b] = cost[b][a] = c; 85 } 86 int num1, num2; 87 num1 = prim (); 88 num2 = smst (num1); 89 printf ("%d %d ", num1, num2); 90 } 91 return 0; 92 }