最小生成树Prim

首先解释什么是最小生成树,最小生成树是指在一张图中找出一棵树,任意两点的距离已经是最短的了。

算法要点:

1、用book数组存放访问过的节点。

2、用dis数组保存对应下标的点到树的最近距离,这里要注意,是对树最近的距离,而不是源点,这和单源最短路径是有区别的。

3、用maps数组保存边的关系。

4、每次先找到离树最近的且没有被访问过的点,以这点的所有边去更新dis数组,也就是更新和树的最近距离。

算法模型:

for(循环n-1次,因为默认1点为起始点,已经被访问了)

{

         for(循环n次。)

        {

                 利用book数组,找到dis中的最近点,且没被访问过的点。

        }

        记录该点被访问,记录当前dis该点的距离存放至答案。

         for(循环n次)

        {

               利用book数组,找到没有被访问过的点,用该点的所有边更新dis数组,也就是更新和树的最近距离。

        }

}

#include<cstdio>
#include<cstdlib>
#include<iostream>

using namespace std;
/*最小生成树Prim未优化版*/

int book[100];//用于记录这个点有没有被访问过
int dis[100];//用于记录距离树的距离最短路程
int MAX = 99999;//边界值
int maps[100][100];//用于记录所有边的关系

int main()
{
    int i,j,k;//循环变量
    int n,m;//输入的N个点,和M条边
    int x,y,z;//输入变量
    int min,minIndex;
    int sum=0;//记录最后的答案
    
    cin>>n>>m;

    //初始化maps,除了自己到自己是0其他都是边界值
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if(i!=j)
                maps[i][j] = MAX;
            else
                maps[i][j] = 0;
        }
    }
            
    for (i = 1; i <= m; i++)
    {
        cin>>x>>y>>z;//输入的为无向图
        maps[x][y] = z;
        maps[y][x] = z;
    }

    //初始化距离数组,默认先把离1点最近的找出来放好
    for (i = 1; i <= n; i++)
        dis[i] = maps[1][i];

    book[1]=1;//记录1已经被访问过了

    for (i = 1; i <= n-1; i++)//1已经访问过了,所以循环n-1次
    {
        min = MAX;//对于最小值赋值,其实这里也应该对minIndex进行赋值,但是我们承认这个图一定有最小生成树而且不存在两条相同的边
        //寻找离树最近的点
        for (j = 1; j <= n; j++)
        {
            if(book[j] ==0 && dis[j] < min)
            {
                min = dis[j];
                minIndex = j;
            }
        }

        //记录这个点已经被访问过了
        book[minIndex] = 1;
        sum += dis[minIndex];

        for (j = 1; j <= n; j++)
        {
            //如果这点没有被访问过,而且这个点到任意一点的距离比现在到树的距离近那么更新
            if(book[j] == 0 && maps[minIndex][j] < dis[j])
                dis[j] = maps[minIndex][j];
        }
    }

    cout<<sum<<endl;
}

/*

6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
Result:19

*/

以上这个算法是没有优化过的,优化的方法很多,堆排序,邻接表等等。有兴趣可以继续看看。

主要想说的是最小生成树和单源最短路径是有区别的,虽然看起来代码比较像,但是本质有些不同,看到题目的时候,还是要好好去分析使用什么方法去做。

原文地址:https://www.cnblogs.com/linkstar/p/5331349.html