当前位置: 首页 > 工具软件 > prime > 使用案例 >

最小生成树——prime算法

上官德寿
2023-12-01

最小生成树的prime算法是以点为核心来进行计算.

原理:从一个点开始遍历它到其他所有点的距离,无法直接到达的距离为INF,记录为mindis数组

如:一共有四个点ABCD 五条边

A——B   2;    A——C   1;        A——D   3;        B——C   4;        C——D   2;

选取A为第一个点,那么mindis数组中的值为0,2,1,3;并将A标记为已经访问过的点;

然后从未访问过的点中找最小的值加入生成树,即此时mindis数组的最小值为1(即A——C的距离最短),为C点,将C加入生成树(即标记C已经访问),并将sum加上权值1;

现在生成树中有两个点A和C,更新mindis数组,即看C到各个点的值与原来mindis数组中的值哪一个小,此时C——D的权值为2,mindis中到D的权值为3,所以更新mindis,更新后为0,2,1,2;

重复上述步骤直到访问所有点

下面是代码

#include <iostream>
#include<cstring>
using namespace std;
int ma[5005][5005];
int mindis[5005];
bool vis[5005];
const int INF=0x3f3f3f;
int main()
{
    std::ios::sync_with_stdio(false);
    memset(ma,INF,sizeof(ma));
    int n,m;
    cin>>n>>m;
    int i;
    for(i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        ma[a][b]=ma[b][a]=min(c,min(ma[a][b],ma[b][a]));//输入到各个点的最小值
    }
    for(i=1;i<=n;i++)
    {
        mindis[i]=ma[1][i];//初始化最短距离数组,目前为第一个点到各个能到的点的最短距离,INF表示到不了
    }
    vis[1]=true;//第一个点已经走过
    bool liantong=true;
    long long cost=0;
    for(i=1;i<n;i++)//n-1次循环,保证访问每一个点
    {
        int tempdis=INF;
        int k=-1;
        for(int j=1;j<=n;j++)//找目前的最短距离
        {
            if(!vis[j]&&mindis[j]<tempdis)
            {
                tempdis=mindis[j];
                k=j;//记录距离最近的点
            }
        }
        if(k==-1)//k==-1,即当前没有点可以走,代表不连通
        {
            liantong=false;//看是否连通
            break;
        }
        cost+=tempdis;
        vis[k]=true;//将这个点标记已访问
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&mindis[j]>ma[k][j])//因为加了一个点进来所以更新最短距离数组,最短距离数组是目前到各个点的最短值
                mindis[j]=ma[k][j];
        }
    }
    if(!liantong)
        cout<<"不连通"<<endl;
    else
        cout<<cost<<endl;
    return 0;
}

 

 类似资料: