基本思想
1. 在图G=(V, E) (V表示顶点 ,E表示边)中,从集合V中任取一个顶点(例如取顶点v0)放入集合 U中,这时 U={v0},集合T(E)为空。
2. 从v0出发寻找与U中顶点相邻(另一顶点在V中)权值最小的边的另一顶点v1,并使v1加入U。即U={v0,v1 },同时将该边加入集合T(E)中。
3. 重复2,直到U=V为止。
这时T(E)中有n-1条边,T = (U, T(E))就是一棵最小生成树。
#include <stdio.h> #define MAXN 100 #define INF (1<<20) int v[MAXN], w[MAXN][MAXN], d[MAXN], ans; int prim(int v0, int n){ int i; for(i=0; i<n; i++){ d[i] = w[v0][i]; v[i] = 0; } v[v0] = 1; ans = 0; for(i=1; i<n; i++){ int x, y, m = INF; for(y=0; y<n; y++) if(!v[y] && d[y] < m) m = d[x=y]; ans += m; v[x]=1; for(y=0; y<n; y++) if(!v[y] && w[x][y] < d[y]) d[y] = w[x][y]; } return ans; } int main(){ int n, m, i, j; while(scanf("%d %d", &n, &m) == 2 && (n != 0 || m != 0)){ for(i=0; i<n; i++) for(j=0; j<n; j++) w[i][j] = INF; int a, b, c; for(i=0; i<m; i++){ scanf("%d %d %d", &a, &b, &c); if(w[a-1][b-1] > c){ //如果有重边 w[a-1][b-1] = c; w[b-1][a-1] = c; } } printf("%d\n", prim(0, n)); } return 0; }
//重新更正取消icount变量 2013-02-15 21:33:50