#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
*/
最小生成树Prim-加点法
最新推荐文章于 2022-06-08 11:10:24 发布