Prime算法

Prime算法

wiki

poj1258

http://poj.org/problem?id=1258

#include 
#define MAXN 110
#define INF 0x7fffffff
int Edge[MAXN][MAXN], dist[MAXN];
/*
 *  核心思想:
 * 
 *  对于有权连通图。从A节点开始,选中与A相连且权值最小的节点B,AB相连。
 *  那么现在到C,有2种方式,A->C, B->C。这时可能需要更新到C的权值。其他
 *  节点也同样。
 */
void prim(int u0, int N)
{
    int sum = 0;
    for (int i = 0; i < N; ++i)
        dist[i] = Edge[u0][i];
    dist[u0] = -1;                  // 自己所在的节点
    for (int i = 0; i < N - 1; ++i) // 还有n-1个节点
    {
        int min = INF, u = -1;
        for (int j = 0; j < N; ++j)
            if (dist[j] != -1 && dist[j] < min) // 没有选中过,并且值要小
            {
                min = dist[j];
                u = j;
            }
        if (u != -1)
        {
            sum += dist[u];
            dist[u] = -1;                 // 该节点已经访问过了
            for (int j = 0; j < N; ++j)   // 更新到新节点的权值
                if (Edge[u][j] < dist[j]) // edge的值为正,已添加过的节点的值为-1
                    dist[j] = Edge[u][j];
        }
    }
    printf("%d\n", sum);
}

/*
 * 输入:
 * 4
 * 0 4 9 21
 * 4 0 8 17
 * 9 8 0 16
 * 21 17 16 0
 * 
 * 求最小代价生成树。
 */
int main()
{
    int N;
    while (scanf("%d", &N) != EOF)
    {
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                scanf("%d", &Edge[i][j]);
        prim(0, N);
    }
    return 0;
}

你可能感兴趣的:(CS)