prim

基本思想

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

原文地址:https://www.cnblogs.com/tanhehe/p/2890291.html