最小生成树

来源:互联网 发布:软件著作权 邮寄证书 编辑:程序博客网 时间:2024/06/05 02:21
#include <stdio.h>#define INF 0x3f3f3f3f#define MAX_NODE 1000int n, m; // n个点 m条边int map[MAX_NODE][MAX_NODE]; // 邻接矩阵int dis[MAX_NODE]; // 点到最小生成树的距离int vis[MAX_NODE]; // 标记点是否被访问int pre[MAX_NODE]; // 记录上一个节点int prim(int rt) // 返回以rt为根的最小生成树长度{    int i, j, min, pos = rt, sum = 0;    for (i = 0; i < n; ++i)    {        dis[i] = map[pos][i]; // 初始化点到生成树的距离        vis[i] = 0; // 初始化所有点未访问        pre[i] = pos;    }    vis[pos] = 1; // 根节点标记为已访问    for (i = 1; i < n; ++i)    {        min = INF; // 初始化最小边权值为无穷大        for (j = 0; j < n; ++j)        {            if (!vis[j] && min>dis[j]) // 找到一条终点未访问的最小权值边            {                min = dis[j]; // 记录边权值                pos = j; // 记录加入最小生成树的终点            }        }        if (min == INF) // 找不到可连通的边        {            return INF;        }        sum = sum + min; // 最小生成树权值加上当前最小边权        vis[pos] = 1; // 点pos标记为已访问        for (j = 0; j < n; ++j)        {            if (!vis[j] && dis[j]>map[pos][j])            {                dis[j] = map[pos][j]; // 更新所有未访问点到生成树的距离                pre[j] = pos; // 更新前一个节点            }        }    }    return sum; // 返回最小生成树长度}int main(){    int i, j, s, e, w, ans, rt = 0;    scanf("%d%d", &n, &m); // 输入点数和边数    for (i = 0; i < n; ++i)    {        for (j = 0; j < n; ++j)        {            map[i][j] = INF; // 初始化边为最大值        }    }    for (i = 0; i < m; ++i)    {        scanf("%d%d%d", &s, &e, &w); // 输入图        map[s][e] = map[e][s] = w;    }    ans = prim(rt); // 计算最小生成树    if (ans < INF)    {        for (i = 0; i < n; i++)        {            if (rt != i)            {                printf("%d ---> %d : %d\n", pre[i], i, map[pre[i]][i]);            }        }        printf("最小生成树长度: %d\n", ans);    }    else    {        printf("不能生成树!\n");    }    return 0;}
0 0
原创粉丝点击