最小生成树(prim算法)

程序小白,希望和大家多交流,共同学习
你身边是不是也有这样的人,总是有很多的想法,有很多的憧憬,但是真的动手去策划,去实施的几乎没有。而且还要牵连周围的人,觉得是周围的人没有给与足够的支持。
愿你们,多动脑,多行动,不要害怕做孤独的人,不然一切都只是泡沫。

//最小生成树
//实现prim(普鲁姆)加点算法
#include<iostream>
#include<string>
#define MAX_VN 50
#define INF 32767
using namespace std;
//使用邻接表创建图
//prim算法、
//一共有n个顶点,至少需要n-1条边,将这些点连接起来
//prim算法实际上是在所有已经访问过的点的邻接点中找到权重最小的那个,
//并不仅仅是在当前一直顶点邻接点中寻找
typedef string VertexData;

struct ArcNode{
    int adjvex;
    int weight;
    ArcNode *nextArc;
};

struct Vertex{
    VertexData data;
    ArcNode *firstArc;
};

struct AdjList{
    Vertex vertex[MAX_VN];
    int verNum, arcNum;
};
void createAdjList(AdjList &G);
int locateVertex(AdjList &G, VertexData data);
void outputAdjList(AdjList &G);

//最小生成树prim算法
struct EdgeNode{//用来存储每次选中的点的信息
    int u, v, w;//分别是起始点结束点和权重
};
void prim(AdjList &G, EdgeNode *en);
void printEN(AdjList &G, EdgeNode *en);

int main(){
/*
prim
6 20
v1 v2 v3 v4 v5 v6
v1 v2 6
v1 v3 1
v1 v4 5
v2 v1 6
v2 v3 5
v2 v5 3
v3 v1 1
v3 v2 5
v3 v4 5
v3 v5 6
v3 v6 4
v4 v1 5
v4 v3 5
v4 v6 2
v5 v2 3
v5 v3 6
v5 v6 6
v6 v3 4
v6 v4 2
v6 v5 6
*/
    AdjList G;
    createAdjList(G);
    outputAdjList(G);
    EdgeNode *en = new EdgeNode[G.verNum];
    prim(G,en);
    printEN(G, en);
    return 0;
}

void createAdjList(AdjList &G){
    cout << "输入顶点个数和弧的条数:";
    cin >> G.verNum >> G.arcNum;
    cout << "输入顶点信息:";
    for (int i =1; i <= G.verNum; i++){
        cin >> G.vertex[i].data;
        G.vertex[i].firstArc = NULL;
    }
    cout << "输入各条弧的信息:";
    VertexData u, v;
    int w;
    int i, j;
    for (int k = 1; k <= G.arcNum; k++){
        cin >> u >> v >> w;
        i = locateVertex(G, u);
        j = locateVertex(G, v);

        ArcNode *p = new ArcNode;
        p -> weight = w;
        p -> adjvex = j;
        p -> nextArc = G.vertex[i].firstArc;
        G.vertex[i].firstArc = p;
    }
}
int locateVertex(AdjList &G, VertexData data){
    for (int i = 1; i <= G.verNum; i++){
        if (G.vertex[i].data == data){
            return i;
        }
    }
    return -1;
}
void outputAdjList(AdjList &G){
    for (int i = 1; i <= G.verNum; i++){
        cout << i << " ";
        cout << G.vertex[i].data << " -> ";
        ArcNode *p = G.vertex[i].firstArc;
        while (p){
            cout << p -> adjvex << " " << p -> weight << " -> ";
            p = p -> nextArc;
        }
        cout << " ^" << endl;
    }
}
void prim(AdjList &G, EdgeNode *en){
    int *closeEdge = new int[G.verNum + 1];//记录当前起始点的邻接点
    int *lowCost = new int[G.verNum + 1];//记录当前起始点邻接点的权重
    bool *mark = new bool[G.verNum + 1];//记录各个点是否被访问
    for (int i = 1; i <= G.verNum; i++){
        closeEdge[i] = -1;
        lowCost[i] = INF;
        mark[i] = false;
    }

    VertexData data;
    cout << "输入起始顶点:";
    cin >> data;
    cout<< "1: " << data << endl;

    int s = locateVertex(G, data);
    closeEdge[s] = s;
    lowCost[s] = 0;//起始点的权重设置为0,所以剩下的权重和它点相对应
    mark[s] = true;

    for (int i = 2; i <= G.verNum; i++){//一共要找G.verNum-1个点,已经输入了第一个点
        ArcNode *p = G.vertex[s].firstArc;//从起始点开始寻找!!!!!不是i
        while (p){//对临邻接点进行更新
            int j = p -> adjvex;
            if (!mark[j] && p -> weight < lowCost[j]){
                lowCost[j] = p -> weight;
                closeEdge[j] = s;
            }
            //cout << p -> adjvex << "-" << p -> weight << " "; 
            p = p -> nextArc;
        }

        int min = INF;
        for (int j = 1; j <= G.verNum; j++){
            if (min > lowCost[j] && !mark[j]){
                min = lowCost[j];
                s = j;
            }
            //cout << lowCost[j] << " ";
        }
        //cout << endl;

        cout << i << ": " << G.vertex[s].data << endl;
        mark[s] = true;
        en[i - 1].u = closeEdge[s];//s是在邻接点中找到的,
        //所以在更新邻接点信息的时候,closeEdge[s]是一定存在的
        en[i - 1].v = s;
        en[i - 1].w = min;
    }
    delete []closeEdge;
    delete []lowCost;
    delete []mark;
}
void printEN(AdjList &G, EdgeNode *en){
    int total = 0;
    for (int i = 1; i < G.verNum; i++){
        cout << "(" << G.vertex[en[i].u].data << ", " 
            << G.vertex[en[i].v].data << ", " << en[i].w << ")" << endl;
        total += en[i].w;
    }
    cout << "= " << total << endl;
}

猜你喜欢

转载自blog.csdn.net/cheng_cuo_tuo/article/details/80541888