Prim算法最小生成树c++实现

15 篇文章 0 订阅
1 篇文章 0 订阅

Prim算法最小生成树c++实现

标签(空格分隔): Prim 算法 c++


最近离散课上讲到了Prim算法实现最小生成树,现在用c++来实现。本文代码来源于乔帮主伪代码。

简述

对于给定的带权图G,为了使得生成树T的权w(T)最小,我们可以使用贪心算法。

求最小生成树的贪心法:

1.选择一个初始点 v1 ;
2.为了使得生成树的权极小化,选择 v1 的最小权邻点,并将其连接到 v1
3.选择{ v1,v2 }的最小权邻点,如 v3 ,将其连接
4.重复以上步骤,直到所以点都连在一起,得到生成树

代码实现

#include <iostream>
#include <vector>
#include <limits>
#include <map>

using namespace std;

typedef float Weight;
typedef int Vertex;
typedef pair<Vertex, Vertex> Edge;
typedef vector<Edge> Edges;
typedef map<Vertex, bool> Vertices;
typedef vector<vector<Weight> > GraphMatrix;
typedef vector<pair<Vertex, Weight> > Labels;
float inf = numeric_limits<float>::max();

//求V的最小权邻点
Vertex nearest_neighbour(Vertices& vertices, Labels& label) {
  Vertex u;
  int n = vertices.size();
  Weight w = inf;
  for (int i = 0; i < n; i++) {
    if (!vertices[i] && label[i].second < w) {
      w = label[i].second;
      u = i;
    }
  }
  return u;
}

pair<Edges, Weight> prim(GraphMatrix& g, Vertex s) {
  int n = g.size();
  Vertices V;
  for (int i = 0; i < n; i++)
    V[i] = false;
  V[s] = true;
  Edges E;
  Weight w = 0; // weight of MST
  Labels L(n);
  for (int i = 0; i < n; i++)
    L[i] = make_pair(s, g[s][i]);
  for (int i = 0; i < n - 1; i++) {
    int u = nearest_neighbour(V, L); // 找到最小权的连接点
    V[u] = true;
    E.push_back(make_pair(u, L[u].first));
    w += g[u][L[u].first];
    for (int j = 0; j < n; j++) {
      if (!V[j] && (g[u][j] < inf) && (g[u][j] < L[j].second))
        L[j] = make_pair(u, g[u][j]);
    }
  }
  return make_pair(E, w);
}



int main() {
  int numberOfVertices;
  cin >> numberOfVertices;
  GraphMatrix graph(numberOfVertices);
  for (int i = 0; i < numberOfVertices; i++) {
    for (int j = 0; j < numberOfVertices; j++) {
      Weight w;
      cin >> w; // 如果两点没有连通,则输入0
      if (w == 0) w = inf;
      graph[i].push_back(w);
    }
  }
  pair<Edges, Weight> MST = prim(graph, 0);
  cout << "The weight of MST is: " << MST.second << endl;
  int n = MST.first.size();
  cout << "The edges of MST are: " << endl;
  for (int i = 0; i < n; i++) 
    cout << "(" << MST.first[i].first << ", " << MST.first[i].second << ")" << endl; 
  return 0;
}

输入案例

Input

( 其中0代表两点不连通 )
8
0 3 2 0 0 0 0 0
3 0 3 6 0 0 0 0
2 3 0 0 5 5 0 0
0 6 0 0 2 0 0 2
0 0 5 2 0 4 3 0
0 0 5 0 4 0 4 0
0 0 0 0 3 4 0 6
0 0 0 2 0 0 6 0

Output

The weight of MST is: 21
The edges of MST are:
(2, 0)
(1, 0)
(4, 2)
(3, 4)
(7, 3)
(6, 4)
(5, 4)

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值