最小生成树——Prim算法

假设有一个图 G G G,它的初始状态如下图所示。图有 7 7 7 个顶点以及 12 12 12 条边,每条边都有相应的权值。
最小生成树——Prim算法_第1张图片
假设从点 v 1 v1 v1 开始,其他所有顶点都相应更新信息, v 1 v1 v1 加入最小生成树中。
最小生成树——Prim算法_第2张图片
每次选取权值最小的那条边所连的点,把该点加入最小生成树,并更新其他顶点的信息。
最小生成树——Prim算法_第3张图片
最小生成树——Prim算法_第4张图片
最小生成树——Prim算法_第5张图片
最小生成树——Prim算法_第6张图片
最小生成树——Prim算法_第7张图片
最小生成树——Prim算法_第8张图片
最小生成树——Prim算法_第9张图片
最小生成树——Prim算法_第10张图片
最小生成树——Prim算法_第11张图片
程序如下

#include 
#include 
using namespace std;

const int maxn = 100;
const int INF = 1e9;

int sum;

//邻接表存储结构
//结点每次插入在adjlist[p]中的链里已有结点的左边而不是从左往右插入
typedef struct edge_node // 边结点
{
     
    int adj_end; // 该边终点编号
    int weight;
    struct edge_node *next_edge;
} edgenode;

typedef struct //邻接表头结点
{
     
    string data;
    edgenode *frist_vertex;
} head_node; 

typedef struct // 邻接表
{
     
    int vertex, edge;
    head_node adjlist[maxn];
} adjGraph;

void createGraph(adjGraph & g)
{
     
    cout << "Enter the number of vertex and edge of graph:" << endl;
    cin >> g.vertex >> g.edge;
    cout << "Enter vertex in graph:" << endl;
    for (int i = 1; i <= g.vertex; i++) {
     
        cin >> g.adjlist[i].data;
        g.adjlist[i].frist_vertex = NULL;
    }
    int x, y, weight;
    cout << "Enter A to B and weight in graph:" << endl;
    for (int i = 1; i <= g.edge; i++) {
     
        cin >> x >> y >> weight;
        edgenode *s = new edgenode;
        s->adj_end = y;
        s->weight = weight;
        s->next_edge = g.adjlist[x].frist_vertex; // 等号左边指向等号右边
        g.adjlist[x].frist_vertex = s;
        s = new edgenode;
        s->adj_end = x;
        s->weight = weight;
        s->next_edge = g.adjlist[y].frist_vertex;
        g.adjlist[y].frist_vertex = s;
    }
}

struct vexValue
{
     
    int adjnode; // 到最近顶点的距离
    int weight;
};

int minium(vexValue a[], int vertex)
{
     
    int k = -1;
    int mine = INF;
    for (int i = 1; i <= vertex; i++) {
     
        if (a[i].weight != 0 && a[i].weight < mine) {
     
            mine = a[i].weight;
            k = i;
        }
    }
    return k;
}

void prim(adjGraph & g, int start)
{
     
    vexValue *closedge = new vexValue[g.vertex];
    closedge[start].adjnode = 0;
    closedge[start].weight = 0;
    for (int i = 1; i <= g.vertex; i++) {
     
        if (i != start) {
     
            closedge[i].adjnode = start;
            closedge[i].weight = INF;
        }
    }
    edgenode *p = g.adjlist[start].frist_vertex;
    while (p) {
     
        closedge[p->adj_end].weight = p->weight;
        p = p->next_edge;
    }
    for (int i = 1; i <= g.vertex - 1; i ++) {
     
        int k = minium(closedge, g.vertex);
        cout << "(" << closedge[k].adjnode << ", " << k << ")" << endl;
        sum += closedge[k].weight;
        closedge[k].weight = 0;
        edgenode *p = g.adjlist[k].frist_vertex;
        while (p) {
     
            if (p->weight < closedge[p->adj_end].weight) {
     
                closedge[p->adj_end].adjnode = k;
                closedge[p->adj_end].weight = p->weight;
            }
            p = p->next_edge;
        }
    }
    delete [] closedge;
}

int main()
{
     
    adjGraph g;
    createGraph(g);
    prim(g, 1);
    cout << "The total value of the spanning tree is " << sum << endl;
    return 0;
}

参考:https://www.bilibili.com/video/BV1He411W7Vh?from=search&seid=17708808766944006067

你可能感兴趣的:(笔记)