1 //本代码解决,一个图的最小生成树的各边权值总和 2 3 #include<iostream> 4 using namespace std; 5 //static声明静态变量,只运行一次, const限定一个变量不允许被改变,产生静态作用。 6 static const int MAX = 100; 7 static const int INFTY = (1<<21); 8 static const int WHITE = 0; 9 static const int GRAY = 1; 10 static const int BLACK = 2; 11 12 int n, M[MAX][MAX]; 13 14 int prim() { 15 int u, minv; 16 /* 17 1.d[v]记录连接内顶点与V - T 内顶点的边中,权值最小的边的权值 18 2.p[v]记录MST中顶点的父节点 19 */ 20 int d[MAX], p[MAX], color[MAX]; 21 22 for(int i = 0; i < n; i++) { 23 d[i] = INFTY; 24 p[i] = -1; 25 color[i] = WHITE; 26 } 27 28 d[0] = 0; 29 30 while(1) { 31 minv = INFTY; 32 u = -1; 33 for(int i = 0; i < n; i++) { 34 if(minv > d[i] && color[i] != BLACK){ 35 u = i; 36 minv = d[i]; 37 } 38 } 39 //所有点都被遍历结束循环 40 if(u == -1) break; 41 42 color[u] = BLACK; 43 //更新与之相关的顶点 44 for(int v = 0; v < n; v++) { 45 if(color[v] != BLACK && M[u][v] != INFTY) { 46 if(d[v] > M[u][v]) { 47 d[v] = M[u][v]; 48 p[v] = u; 49 color[v] = GRAY; 50 } 51 } 52 } 53 } 54 55 int sum = 0; 56 for(int i = 0; i < n; i++) { 57 if(p[i] != -1) sum += M[i][p[i]]; //这里为什么不用sum+=d[i]呢,因为害怕它不是连通图 58 } 59 return sum; 60 } 61 62 int main() { 63 cin >> n; 64 //构建邻接矩阵 65 for(int i = 0; i < n; i++) { 66 for(int j = 0; j < n; j++) { 67 int e; 68 cin >> e; 69 M[i][j] = (e == -1) ? INFTY: e; 70 } 71 } 72 73 cout << prim() << endl; 74 return 0; 75 } 76 /* 77 5 78 -1 2 3 1 -1 79 2 -1 -1 4 -1 80 3 -1 -1 1 1 81 1 4 1 -1 3 82 -1 -1 1 3 -1 83 */