输入:
输入的第一行包含一个正整数n,表示图中共有n个顶点。其中n不超过50。
以后的n行中每行有n个用空格隔开的整数,对于第i行的第j个整数,如果不为0,则表示第i个顶点和第j个顶点有直接连接且代价为相应的值,0表示没有直接连接。当i和j相等的时候,保证对应的整数为0。
输入保证邻接矩阵为对称矩阵,即输入的图一定是无向图,且保证图中只有一个连通分量。
输出:
只有一个整数,即最小生成树的总代价。请注意行尾输出换行。
样例输入:
4 0 2 4 0 2 0 3 5 4 3 0 1 0 5 1 0
样例输出:
6
#include <iostream>
using namespace std;
#define MVNum 50 // 顶点个数上限
#define MAXInt 1000000000// 设置最大值
typedef struct // 定义图结构
{
int vexnum; // 图中顶点个数
int arcs[MVNum][MVNum]; // 邻接矩阵
}AMGraph;
struct CloseEdge // 定义辅助数组(记录每个顶点到顶点集合的权值及该边始点)的结构
{
int adjvex; // 始点
int lowcost; // 边的权值
};
void CreateAM(AMGraph &G) // 创建图
{
int i, j;
cin >> G.vexnum; // 输入顶点个数
for(i = 0; i < G.vexnum; i++)
{
for(j = 0; j < G.vexnum; j++)
{
cin >> G.arcs[i][j];
if(G.arcs[i][j] == 0) G.arcs[i][j] = MAXInt;
}
}
}
int Min(struct CloseEdge closedge[], int vexnum) // 找剩余顶点到顶点集合的边的权值最小的顶点
{
int i, k, min = MAXInt;
for(i = 0; i < vexnum; i++)
{
if(closedge[i].lowcost != 0 && closedge[i].lowcost < min)
{
min = closedge[i].lowcost;
k = i;
}
}
return k;
}
void MiniSpanTree_Prim(AMGraph G, int u) // 建立最小生成树
{
struct CloseEdge closedge[MVNum]; // 定义辅助数组
int i, j, k, cost, u0, v0, min = 0;
k = u; // 看传过来的参数u的值,这里为0,即 k = 0
for(j = 0; j < G.vexnum; j++)
{
if(j != k) // k = 0
{
closedge[j].adjvex = k;
closedge[j].lowcost = G.arcs[k][j];
}
}
closedge[k].lowcost = 0; // 将第一个顶点加入顶点集合u
for(i = 1; i < G.vexnum; i++)
{
k = Min(closedge, G.vexnum);
u0 = closedge[k].adjvex;
v0 = k;
min += closedge[k].lowcost;
closedge[k].lowcost = 0; // 将k加入顶点集合u
for(j = 0; j < G.vexnum; j++) // 顶点集合u加入新元素后需要检查更新剩余顶点到顶点集合的边的始点和权值
{
if(G.arcs[k][j] < closedge[j].lowcost)
{
closedge[j].adjvex = k;
closedge[j].lowcost = G.arcs[k][j];
}
}
}
cout << min;
}
int main()
{
AMGraph G;
CreateAM(G);
MiniSpanTree_Prim(G, 0);
return 0;
}