• Prim算法求最小生成树


    Prim算法: 采用贪婪算法,通过迭代逐步加入权重最小的边进行构造。

    伪代码:

    1,初始化U={u0},E为空集;  //E是最小生成树的边集合,U是其顶点集合,选定构造最小生成树的出发点u0

    2,重复以下步骤直到U=V;

    2.1 以顶点集U和顶点集V-U之间的所有边作为侯选边,从中寻找权值最小的边(u,v)

    2.2 令U=U∪{v},E=E∪{(u,v)}

      1 #include <iostream>
      2 #include <vector>
      3 #include <queue>
      4 #include <string>
      5 #include <climits>
      6 
      7 using namespace std;
      8 
      9 template<class T>
     10 struct GraphNode
     11 {
     12     bool visited;
     13     int index;
     14     int weight;
     15     T vertexName;
     16                                                         //自定义优先级:weight小的优先
     17     friend bool operator<(GraphNode a, GraphNode b) {
     18         return a.weight > b.weight;
     19     }
     20 };
     21 
     22 template<class T>
     23 class Graph
     24 {
     25 public:
     26     Graph() {}
     27     Graph(int * vertexArray, T * nameOfVertex, int numberOfVertex);
     28 
     29     //Prim
     30     void Prim(int source);
     31 
     32 private:
     33     int vertexNum, arcNum;
     34     vector<vector<int>>adjacencyMatrix;                    //邻接矩阵
     35     vector<GraphNode<T>>graphNodeArray;                    //顶点信息,只初始化index和vertexName
     36 };
     37 
     38 
     39 int main()
     40 {
     41     const int numofVertex = 7;
     42     int cost[numofVertex][numofVertex] = {
     43         { INT_MAX,       12 ,          5 ,      11 ,INT_MAX ,    INT_MAX ,INT_MAX },
     44         { 12,      INT_MAX ,    INT_MAX ,INT_MAX ,     33 ,    INT_MAX ,INT_MAX },
     45         { 5,          INT_MAX , INT_MAX ,     21 ,INT_MAX ,      19 ,INT_MAX },
     46         { 11,      INT_MAX ,      21 ,INT_MAX ,     28 ,       8 ,INT_MAX },
     47         { INT_MAX,        33, INT_MAX ,     28 ,INT_MAX , INT_MAX ,      6 },
     48         { INT_MAX, INT_MAX ,      19 ,      8 ,INT_MAX , INT_MAX ,     16 },
     49         { INT_MAX, INT_MAX , INT_MAX ,INT_MAX ,      6 ,      16 ,INT_MAX }
     50     };
     51     //初始化各顶点
     52     string verName[numofVertex] = { "A","B","C","D","E","F","G" };
     53     Graph<string>g(*cost, verName, numofVertex);
     54 
     55     cout << "Prim算法执行结果:" << endl;
     56     try {
     57         g.Prim(0);
     58     }
     59     catch (...) {
     60         cout << "算法执行失败" << endl;
     61     }
     62     system("pause");
     63     return 0;
     64 }
     65 
     66 template<class T>
     67 Graph<T>::Graph(int * vertexArray, T * nameOfVertex, int numberOfVertex)
     68 {
     69     vertexNum = numberOfVertex;                        //顶点数
     70     arcNum = 0;
     71     GraphNode<T> tempgraphNode;
     72     for (int i = 0; i < vertexNum; i++)
     73     {
     74         tempgraphNode.index = i;
     75         tempgraphNode.vertexName = nameOfVertex[i];
     76         graphNodeArray.push_back(tempgraphNode);
     77     }
     78     //分配所需空间
     79     adjacencyMatrix.resize(vertexNum, vector<int>(vertexNum));
     80     for (int i = 0; i < vertexNum; i++)
     81         for (int j = 0; j < vertexNum; j++)
     82             adjacencyMatrix[i][j] = *(vertexArray + i*vertexNum + j);
     83 }
     84 
     85 template<class T>
     86 void Graph<T>::Prim(int source)
     87 {
     88     int vertextNum = adjacencyMatrix.size();
     89     if (source > vertexNum)
     90         throw"位置";
     91 
     92     vector<int>path(vertexNum);
     93     priority_queue<GraphNode<T>>queue;
     94     int minIndex;
     95     graphNodeArray.resize(vertextNum);                //重置足够空间
     96 
     97     for (int i = 0; i < vertextNum; i++)
     98     {
     99         graphNodeArray[i].visited = false;
    100         graphNodeArray[i].weight = INT_MAX;
    101         path[i] = source;                            //记录U 集合双亲关系
    102     }
    103     graphNodeArray[source].weight = 0;
    104     queue.push(graphNodeArray[source]);
    105 
    106     while (!queue.empty())
    107     {
    108         GraphNode<T> tempGraphNode = queue.top();
    109         queue.pop();
    110         if (tempGraphNode.visited)
    111             continue;
    112         tempGraphNode.visited = true;
    113         minIndex = tempGraphNode.index;                //两个集合之间的权值最小边对应的V-U 中顶点的序号
    114         for(int j=0; j<vertextNum; j++)
    115                                                     //两个集合之间的权值最小边对应的V-U中的顶点 的关联边入队
    116             if (j != minIndex && !graphNodeArray[j].visited&&adjacencyMatrix[minIndex][j] < graphNodeArray[j].weight)
    117             {
    118                 path[j] = minIndex;
    119                 graphNodeArray[j].weight = adjacencyMatrix[minIndex][j];
    120                 queue.push(graphNodeArray[j]);        //边入队,顺便找到其在队中位置
    121             }
    122     }
    123     for (int j = 0; j < vertextNum; j++)
    124     {
    125         int priorindex = path[j];
    126         if (priorindex != j)
    127             cout << graphNodeArray[priorindex].vertexName << "----" << graphNodeArray[j].vertexName << " ";
    128     }
    129     cout << endl;
    130 }

    参考前一篇:   Kruskal    

  • 相关阅读:
    1137. 第 N 个泰波那契数
    486. 预测赢家
    python函数—函数的参数+递归函数
    python函数—调用函数+定义函数
    Seize the day
    数学建模基础学习2-matlab + lingo
    Python基础--使用list和tuple+条件判断+使用dict和set
    经济学人精读丨中国的电子商务
    数学建模基础学习1
    C盘今天爆掉了,罪魁祸首--百度云管家
  • 原文地址:https://www.cnblogs.com/guoyujiang/p/12056309.html
Copyright © 2020-2023  润新知