最小生成树Prim-加点法

#include <iostream>
#include<bits/stdc++.h>
#define INF 1000
using namespace std;
struct ShortEdge
{
    int  adjvex;
    int lowcost;
};
int arc[100][100];
int vexNum;
int arcNum=0;
ShortEdge shortEdge[100];
void Input()
{
    cin>>vexNum;
    for(int i=0; i<vexNum; i++)
    {
        for(int j=0; j<vexNum; j++)
        {
            cin>>arc[i][j];
            if(arc[i][j]==0)//0表示没有边
                arc[i][j]=INF;
        }
    }
}
int MinEdge()
{
    int minDis=INF;
    int index=-1;
    for(int i=0; i<vexNum; i++)
    {
        if(shortEdge[i].lowcost!=0&&shortEdge[i].lowcost<minDis)
        {
            minDis=shortEdge[i].lowcost;
            index=i;
        }
    }
    return index;
}
/**
* Prim算法 :从待选点集里找到里已选点集中的最近的点加入已点选集
* 给定出发点start
* 找出start 与vexNum个顶点的距离存入shortEdge数组,并标记start节点已经被访问(加入已选点集)
shortEdge[i] :表示以shortEdge[i].adjvex和i为顶点的边;         shortEdge[i] .lowcost==0表示已经加入已选集合
* 然后从shortEdge数组中找到在未访问顶点里距离已选点集最近的点的下标(即里找到最短边的下标minIndex)
* 输出该最短边的信息
* 更新shortEdge数组(因为加入minIndex的点可能会拉近已选点集到未选点集的距离)
*
*/
void Prim(int start)
{
    //初始化,已选点集为start,已选点集与未选点集之间的距离为start与各顶点的距离
    for(int i=0; i<vexNum; i++)
    {
        shortEdge[i].adjvex=start;
        shortEdge[i].lowcost=arc[i][start];
    }
    shortEdge[start].lowcost=0;
    //vexNum个顶点,最小生成树有VexNum-1条边
    for(int i=0; i<vexNum-1; i++)
    {
        /**
        for(int i=0; i<vexNum; i++)
            cout<<shortEdge[i].adjvex<<"    "<<i<<"   "<<shortEdge[i].lowcost<<endl;*/
        int minIndex=MinEdge();//找最近点的下标
        cout<<shortEdge[minIndex].adjvex<<"-----"<<minIndex<<" "<<shortEdge[minIndex].lowcost<<endl;
        shortEdge[minIndex].lowcost=0;

        //更新shortEdge数组,这个时候,把已选点集看成一个整体,
        for(int j=0; j<vexNum; j++)
        {
            //cout<<j<<endl;
            if(shortEdge[j].lowcost>arc[minIndex][j])
            {
                shortEdge[j].lowcost=arc[minIndex][j];
                shortEdge[j].adjvex=minIndex;
            }
        }
    }
}

int main()
{
    Input();
    Prim(5);
    //cout << "Hello world!" << endl;
    return 0;
}
/**
6
0 34 46 0 0 19
34 0 0  0 12 0
46 0 0 17 0 25
0 0 17 0 38 25
0 12 0 38 0 26
19  0 25 25 26 0



5-----0 19
5-----2 25
2-----3 17
5-----4 26
4-----1 12
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值