Prim算法

来源:互联网 发布:网络信贷 编辑:程序博客网 时间:2024/06/16 01:19

贪心算法---prim算法。

G=(V,E)-----V顶点集合,E为权值集合,

1)S={1}加入顶点集//例如第一个加入是1,i属于S,j属于V-S集合中找出C[i][j]最小的全职,此时将j加入S;

2)此时S集合中点数为2,j又在 V-S中取值。

3)循环找到最小的值,纪录点。知道找完为止。

4)这里要注意是找两个集合最近权值。

设计代码:

#include <iostream>

using namespacestd;

#define Not 10000

//设计在这里Not表示为不通,就是没有改路

#define N 100

//最多有这么多点

int Graph[N][N];

int MinValue[N];

//表示为以N点为终点的最小权值

int MST[N];

//用来记录上面得到的最小权值的点


//设计一个的到最小权值的,这里是以start为起点

int prim(int length,int start)

{

    for(int i=1;i<=length;++i)

    {

        //这里是以start起点,当然要把它排出去

        if(i!=start)

        {

            //先记录第一次选择,start点附近的所有的值

            MinValue[i]=Graph[start][i];

            MST[i]=start;

            //添加该点

        }

    }

    MST[start]=0;

    //表示加入了改点,start其实是起点

    int min,sum=0;

    int minid=0;

    //sum用来记录最小的权值的

    for(int i=1;i<=length;++i)

    {

        if(i!=start)

        {

            min=Not;

            minid=0;

            for(int j=1;j<=length;++j)

            {

               if(j!=start)

               {

                   if(MinValue[j]<min&&MinValue[j]!=0)

                   {

                       min=MinValue[j];

                       minid=j;

                   }

               }

            //找到最小值,而且用minid记录它的位置;

            }

            //现在可以在此打印

            cout<<"V"<<MST[minid]<<""<<"-v"<<minid<<"="<<min<<endl;

            sum+=min;

            //加上此时的最小权值

           //将此时对应的最小的权值设为0,表示它已经走过了

            MinValue[minid]=0;

            for(int j=1;j<=length;++j)

            {

                if(j!=start)

                {

                    if(Graph[minid][j]<MinValue[j])

                    {

                        MinValue[j]=Graph[minid][j];

                        MST[j]=minid;

                    }

                }

            }

        }

    }

    return sum;

}


int main(int argc,const char * argv[]) {

    // insert code here...

    std::cout <<"算法请输入顶点的个数:\n";

    int n;

    cin>>n;

    int start;

    cout<<"输入您开始的点是";

    cin>>start;

    for(int i=1;i<=n;++i)

    {

        for(int j=1;j<=n;++j)

            Graph[i][j]=Not;

        //进行初始化

    }

    cout<<"构建图形:\n";

    for(int i=1;i<=n;++i)

    {

        for(int j=1;j<=n;++j)

        {

            if(i==j)Graph[i][j]=Not;

            else{

            cout<<"10000表示为不可达他是无限大的,其他的输入正常的点:("<<i<<","<<j<<"):";

            cin>>Graph[i][j];

            }

        }

        

    }

    int sum=prim(n, start);

    cout<<sum<<endl;

    return 0;

}

用例测试:
希望大家指出不足之处。学生感激不尽。