重学数据结构系列之——图论算法之Prim算法
2016-04-16 22:10
411 查看
1.首先了解一些概念:
生成树:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。(简单来说就是顶点不变,但边数是n-1条,而且抽取出来后,图还是连通的)最小生成树:如何从一个带权图中抽出一棵生成树,使得边权值和最小,这棵生成树就叫做最小生成树。(就是找生成树中权值之和最小的)
2.Prim算法
即普里姆算法,简单来说就是从一个点出发,每次取出了生成树中的边以外最小的边Prim 算法一般应用于边较为稠密的图,也就是顶点较少、而边较多的图。
3.代码实现
#include <iostream> #include <cstring> #include <vector> #include <queue> using namespace std; //定义一个大整数,下面表示距离很远就对了 const int INF = 0x3f3f3f3f; //一个边的结构 struct Edge { //vertex:一条边的另一个端点 //weight:该边权重 int vertex, weight; }; class Graph{ private: int n; bool *visited; vector<Edge> *edges; //邻接表 public: //dist(distance)://用于保存某个顶点到生成树的距离 int *dist; Graph(int input_n){ n = input_n; edges = new vector<Edge> ; dist = new int ; memset(visited, 0, n * sizeof(bool)); //初始化每个dist为0x3f3f3f3f,这是个大整数,表示距离很远 memset(dist,0x3f, n * sizeof(int)); } ~Graph(){ delete[] dist; delete[] visited; delete[] edges; } void insert(int x, int y, int weight) { Edge edge1,edge2; <span style="white-space:pre"> </span>edge1.vertex = x; <span style="white-space:pre"> </span>edge1.weight = weight; <span style="white-space:pre"> </span>edge2.vertex = y; <span style="white-space:pre"> </span>edge2.weight = weight; <span style="white-space:pre"> </span>edges[x].push_back(edge2); <span style="white-space:pre"> </span>edges[y].push_back(edge1); } //v:起点 int prim(int v){ //定义并初始化总权值为0 int total_weight = 0; //起点距离起点的距离为0 dist[v] = 0; for (int i = 0; i < n; i++) {//外层循环是要找到n个顶点 int min_dist = INF, min_vertex; //初始化最小距离为一个大的整数,min_vertex为最小距离的那个点的编号 //从n个点中找最近的顶点(离生成树最近的),i=0时,当然是起点自己离自己(暂时生成树只有起点)最近啦,而且我们初始化其距离为0了,下一个循环是更新这个点连着的边 另外一个端点的距离为其边的权值 for (int j = 0; j < n; j++) { //若没访问过,且距离小于最小距离 if (!visited[j] && dist[j] < min_dist) { //更新最小距离 min_dist = dist[j]; //保存最小的顶点的编号 min_vertex = j; } } //加上最小距离(权值) total_weight += min_dist; //设置为已访问 visited[min_vertex] = 1; //枚举这个结点的所有的边 for(Edge &j : edges[min_vertex]){ //如果边的另一个端点没访问过且权值小于距离 if(!visited[j.vertex] && j.weight < dist[j.vertex]){ //就更新其距离为边的权值 dist[j.vertex] = j.weight; } } } return total_weight; } }; int main() { int n, m; cin >> n >> m; Graph g(n); for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; g.insert(a, b, c); } cout << g.prim(0) << endl; return 0; }
运行环境:
C++11
输入按照下图输入
相关文章推荐