最小生成树之Prim算法 C++实现

Prim算法大致介绍(个人理解)

1:图中所有的点组成了一个集合set,从集合set中随意选取一个点s,开始进行该算法,

2:从set中将该点s删除,并将该点s加入到另外一个集合now中,now初始为空

3:对now中的所有节点进行遍历,找到距离now的最近的那个非集合now的节点,并将该节点从set中删除,加入now中,

4:重复步骤3,直到set集合为空

无向图:

#include<map>
#include<vector>
#include<string>
#include<set>
#include<queue>
#include<limits>
#include<iostream>
using namespace std;
queue<string> pre;  //存放所有元素的一个队列,数据输入完队列就建立好了,算法开始后队列元素依次出队列,进入now中,队列为空时说明所有节点都已经遍历完全
vector<string> now;  //存放从队列出来的元素,即已经找到路径的节点,用vector便于取数据
set<string> nowset;  //用set存放从队列出来的元素,便于查找
map<string, vector<string> > relation;  //存放节点和与该节点相邻节点的关系
int prim(map<string, map<string, int> > link)  //prim算法。贪心策略,最小生成树
{
 string head;
 int total = 0;
 head = pre.front();  //选取一个节点为最先开始进行该算法的点
 pre.pop();  //从队列弹出,并且进入now中
 now.push_back(head);
 nowset.insert(head);
 while (!pre.empty())
 {
  int i = 0,j=0,min=0,flag=0; 
  string start, end;
  //遍历已经找到路径的节点(now中的节点),找这些节点的邻接节点,每一个路径都会有个权值,找到最小权值,则此次循环可以添加一个节点进入
  //now中,同时添加一条路径
  for (i = 0; i < now.size(); i++)  
  {
   for (j = 0; j < relation[now[i]].size(); j++)
   {
    if (nowset.find(relation[now[i]][j]) == nowset.end()) //在nowset里没有该元素,则找最小权值
    {
     if (flag == 0) //每当now新添加了元素,都要进行一次搜索,找到距离now集合最近的那个点,所以每次都要设个flag
     {
      min = link[now[i]][relation[now[i]][j]];  //给min赋值,每次对now容器中的元素求最小权值时都要先给min确定个初值
      flag = 1;
     }
     if (link[now[i]][relation[now[i]][j]] <= min)
     {
      min = link[now[i]][relation[now[i]][j]];
      //cout << min << endl;
      start = now[i];
      end = relation[now[i]][j];
     }
    }
   }
  }
  cout << "[" << start << "<->" << end << "]" << endl;  //打印链路
  pre.pop();
  now.push_back(end);
  nowset.insert(end);
  total += min;
 }
 return total;
}
int main()
{
 map<string, map<string, int> > link; //邻接关系和权值
 int x,i=0,y;
 cin >> x; //邻接关系个数
 string s, e;
 for (i = 0; i < x; i++)
 {
  cin >> s >> e >> y;
  link[s][e] = y;
  link[e][s] = y;
  relation[s].push_back(e);
  relation[e].push_back(s);
 }
 map<string, vector<string> >::iterator it;
 for (it = relation.begin(); it != relation.end(); it++)
 {
  pre.push(it->first);
 }
 cout << prim(link) << endl;
}
//输入:
6
a b 3
a d 6
a c 2
b d 7
b c 5
d c 1

//输出:
[a<->c]
[c<->d]
[a<->b]
6
时间: 2024-10-30 12:29:01

最小生成树之Prim算法 C++实现的相关文章

最小生成树(prim算法,Kruskal算法)c++实现

1.生成树的概念 连通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树. 生成树是连通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则将出现一个回路:若去掉一条边,将会使之变成非连通图. 生成树各边的权值总和称为生成树的权.权最小的生成树称为最小生成树. 2.最小生成树的性质用哲学的观点来说,每个事物都有自己特有的性质,那么图的最小生成树也是不例外的.按照生成树的定义,n 个顶点的连通网络的生成树有 n 个顶点.n-1 条边. 3.构造最小生成树,要解决以下两个问题

最小生成树之Prim算法

Prim算法: 假设N = (V,{E})是连通网,TE是N上最小生成树中边的集合.算法从U={u0}(u0属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止,此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树. 为实现这个算法,需附设一个辅助数组closedge,以记录从U到V-U具有最小代价的边.对每个顶点vi属于V-U,在辅助数组中存在一个相应分量clos

hihoCoder #1097 最小生成树之Prim算法

原题网址,http://hihocoder.com/problemset/problem/1097 #1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但 是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道路所需要的费用,小Hi希望知道,最少花费多少就 可以使得任意两座城市都可以通过所建

Hihocoder 之 #1097 : 最小生成树一&#183;Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)

#1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道路所需要的费用,小Hi希望知道,最少花费多少就可以使得任意两座城市都可以通过所建造的道路互相到达(假设有A.B.C三座城市,只需要在AB之间和BC之间建造道路,那么AC之间也是可以通过

hihoCoder - hiho一下 第二十六周 - A - 最小生成树一&#183;Prim算法

题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来--小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道路所需要的费用,小Hi希望知道,最少花费多少就可以使得任意两座城市都可以通过所建造的道路互相到达(假设有A.B.C三座城市,只需要在AB之间和BC之间建造道路,那么AC之间也是可以通过这两

hihocoder hiho一下 第二十六周 最小生成树一&#183;(Prim算法)

题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道路所需要的费用,小Hi希望知道,最少花费多少就 可以使得任意两座城市都可以通过所建造的道路互相到达(假设有A.B.C三座城市,只需要在AB之间和BC之间建造道路,那么AC之间也是可以通过这

hiho一下 第二十六周---最小生成树一&#183;Prim算法

最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来--小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道路所需要的费用,小Hi希望知道,最少花费多少就可以使得任意两座城市都可以通过所建造的道路互相到达(假设有A.B.C三座城市,只需要在AB之间和BC之间建造道路,那么AC之间也是可以通过这两条道路连通的

最小生成树的Prim算法

构造最小生成树的Prim算法 假设G=(V,E)为一连通网,其中V为网中所有顶点的集合,E为网中所有带权边的集合.设置两个新的集合U和T,其中集合U用于存放G的最小生成树的顶点,集合T用于存放G的最小生成树中的边.令集合U的初值为U={u0}(假设构造最小生成树时是从顶点u0出发),集合T的初值为T={}.Prim算法的思想是:在连通网中寻找一个顶点落入U集,另外一个顶点落入V-U集的这个顶点加入到U集中,然后继续寻找一顶点在U集而另一顶点在V-U集且权值最小的边放入T集;如果不断重复直到U=V

数据结构--图--最小生成树(Prim算法)

构造连通网的最小生成树,就是使生成树的边的权值之和最小化.常用的有Prim和Kruskal算法.先看Prim算法:假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合.算法从U={u0}(uo属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止.此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树.为实现此算法,需另设一个辅助数组closedge,以记录从U

24最小生成树之Prim算法

最小生成树的Prim算法 思想:采用子树延伸法 将顶点分成两类: 生长点--已经在生成树上的顶点 非生长点--未长到生成树上的顶点 使用待选边表: 每个非生长点在待选边表中有一条待选边,一端连着非生长点,另一端连着生长点 步骤: 步骤1)构造初始待选边表,任选一个顶点v作为初始生长点,对其余每个非生长点w(共n-1个),将边(w,v)加进待选边表,如果边(w,v)不存在,则认为边(w,v)的长度是∞. 步骤2)循环n-2遍,非生长点个数k从n-1变到1. ①选择树边. 从待选边表中选出一条最短的