/**
*
* Althor: Hacker Hao
* Create: 2023.12.04
*
*/
# include <bits/stdc++.h>
# define SIZE 20
# define NEWSIZE 20
# define MAXSIZE 100000000 //表示无限大
using namespace std;
//边的结构
typedef struct ArcNode
{
int adjvex; //边的终点
int value; //权值
struct ArcNode* nextarc; //指向下一条边的指针
}ArcNode;
//顶点结构
typedef struct VNode
{
char data;
ArcNode* firstarc; //指向第一条与该顶点有关的边的指针
}VNode;
//图的结构
typedef struct
{
VNode* VNode;
int vexnum, arcnum;
int size;
}Graph;
int* Adjvex; //最小生成树中的顶点
int* Lowcost; //不在最小生成树中的各点到最小生成树中的点的边的最小权值
int* Flag; //标注该点是否已加入最小生成树
void Create(Graph& G) //创建图(邻接表)
{
cout << "请输入顶点和边的个数:";
cin >> G.vexnum >> G.arcnum;
G.VNode = (VNode*)malloc(SIZE * sizeof(VNode));
G.size = SIZE;
while (G.size <= G.vexnum)
{
G.VNode = (VNode*)realloc(G.VNode, (G.size + NEWSIZE) * sizeof(VNode));
G.size += NEWSIZE;
}
Adjvex = (int*)malloc((G.size + 10) * sizeof(int));
Lowcost = (int*)malloc((G.size + 10) * sizeof(int));
Flag = (int*)malloc((G.size + 10) * sizeof(int));
cout << "请输入各顶点的名称:";
for (int i = 1; i <= G.vexnum; i++)
{
cin >> G.VNode[i].data;
G.VNode[i].firstarc = NULL; //邻接表初始化
}
cout << "请输入各边起点和终点的编号及权重:" << endl;
int x, y, w; //x:起始点 y:终点 w:权重
ArcNode* p, * q;
for (int i = 1; i <= G.arcnum; i++)
{
cin >> x >> y >> w;
p = (ArcNode*)malloc(sizeof(ArcNode)); //存放当前边的结点
p->nextarc = NULL;
p->adjvex = y;
p->value = w;
q = G.VNode[x].firstarc;
if (q == NULL)
{
G.VNode[x].firstarc = p;
}
else {
while (q->nextarc != NULL)
{
q = q->nextarc;
}
q->nextarc = p;
}
p = (ArcNode*)malloc(sizeof(ArcNode));
p->nextarc = NULL;
p->adjvex = x;
p->value = w;
q = G.VNode[y].firstarc;
if (q == NULL)
{
G.VNode[y].firstarc = p;
}
else {
while (q->nextarc != NULL)
{
q = q->nextarc;
}
q->nextarc = p;
}
}
}
void MinSpanTree_Prim(Graph& G, int v) //从顶点v出发求图的最小生成树
{
for (int i = 1; i <= G.vexnum; i++) //初始化
{
Adjvex[i] = v;
Lowcost[i] = MAXSIZE;
Flag[i] = 0;
}
Lowcost[v] = 0;
Flag[v] = 1; //把标记初始点
cout << G.VNode[v].data << "->"; //输出初始点
int num = 1; //初始化最小生成树中的点的个数,即初始点
ArcNode* p;
while (num < G.vexnum)
{
p = G.VNode[v].firstarc; //新加入树的点的邻接点
while (p != NULL)
{
if (!Flag[p->adjvex] && Lowcost[p->adjvex] > p->value)
{
Lowcost[p->adjvex] = p->value;
Adjvex[p->adjvex] = v;
}
p = p->nextarc;
}
int min = MAXSIZE;
for (int i = 1; i <= G.vexnum; i++)
{
if (!Flag[i] && Lowcost[i] < min)
{
min = Lowcost[i];
v = i;
}
}
Flag[v] = 1; //标记该点
cout << G.VNode[v].data << "->"; //输出新加入树的点的值
num++; //最小生成树中的点的个数++
}
cout << "EXIT" << endl;
}
int main()
{
Graph G;
Create(G);
int sum = 0;
cout << "最小生成树为:";
MinSpanTree_Prim(G, 1); //从第一个顶点出发
for (int i = 1; i <= G.vexnum; i++)
{
sum += Lowcost[i]; //求最小生成树的值
}
cout << "最小生成树的中两点间最大距离为:" << sum << endl;
return 0;
}
C/C++: Prim_MinSpanTree
最新推荐文章于 2024-10-08 16:16:22 发布