您的位置:首页 > 编程语言 > C语言/C++

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

2020-02-07 17:06 525 查看

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;
}
[/code]
//输入:
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
[/code]


转载于:https://my.oschina.net/a20092173/blog/505782

  • 点赞
  • 收藏
  • 分享
  • 文章举报
chiqu2336 发布了0 篇原创文章 · 获赞 0 · 访问量 96 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: