首页 > 其他 > 详细

最小生成树(prim)

时间:2015-11-23 00:46:53      阅读:283      评论:0      收藏:0      [点我收藏+]

里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。

 

介绍如下:

http://baike.baidu.com/link?url=nDhHyOlu8i90Hm5bjUycarVdBPN8BXQvnv8NGwl0g4MLlLkmkFLwf7xs1-JBWCRkQw5qDU6cIwh1ov7fyRRxQK

 

原理可以参考这几篇文章:

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

http://blog.csdn.net/weinierbian/article/details/8059129

http://blog.chinaunix.net/uid-25324849-id-2182922.html

 

我是用vector和pair的邻接表实现的,然后用两个list保存两个集合,一个最小生成树集,一个其他集

实现如下:

  1 #include <iostream>
  2 #include <vector>
  3 #include <queue>
  4 #include <list>
  5 using namespace std;
  6 
  7 vector<pair<int,int> > eg[100];
  8 
  9 vector<pair<int,int> > result;
 10 
 11 typedef pair<int,int> pa;
 12 
 13 bool visit[100];
 14 
 15 list<int> setOfPrim;
 16 
 17 list<int> outOfPrim;
 18 
 19 int lowcost[100] = {0};
 20 
 21 void prim(int n,int d)
 22 {
 23           int min,aim,sta;
 24           bool is;
 25 
 26           list<int>::iterator sop;//最小树集合
 27           list<int>::iterator oop;//其他集合
 28           vector<pair<int,int> >::iterator it;
 29 
 30           setOfPrim.push_back(0);//放入起始点0进最小树集合
 31 
 32           //初始化其他集合
 33           for(int i = 1;i<n;i++)
 34                    outOfPrim.push_back(i);
 35 
 36           while(!outOfPrim.empty())//其他集合不为空
 37           {
 38                     //遍历最小树集合,sop,寻找与集合最近的点
 39                     min = 1<<16;
 40                     for(sop = setOfPrim.begin();sop!=setOfPrim.end();sop++)
 41                     {
 42                               //遍历sop邻接点
 43                               for(int i = 0;i<eg[*sop].size();i++)
 44                               {
 45                                         pa x = eg[*sop][i];
 46                                         is = false;
 47 
 48                                         //如果点属于oop集合
 49                                         for(oop = outOfPrim.begin();oop!=outOfPrim.end();oop++)
 50                                         {
 51                                                   if(*oop == x.first)
 52                                                   {
 53                                                             is = true;
 54                                                   }
 55                                         }
 56 
 57                                         if(is)
 58                                         {
 59                                                   if(x.second<min)
 60                                                   {
 61                                                             min = x.second;
 62                                                             aim = x.first;
 63                                                             sta = *sop;
 64                                                   }
 65                                                   //min存放了离sop集合最近的点的距离
 66                                                   //aim存放了点的序号
 67                                         }
 68                               }
 69                     }
 70 
 71                     setOfPrim.push_back(aim);
 72                     result.push_back(make_pair(sta,aim));
 73                     for(oop = outOfPrim.begin(); oop != outOfPrim.end(); )
 74                     {
 75                               if(*oop == aim)
 76                               {
 77                                         oop = outOfPrim.erase(oop);
 78                                         if(outOfPrim.empty())
 79                                                   break;
 80                               }
 81                               else
 82                                         oop++;
 83                     }
 84                     cout<<"The set of prim:\n";
 85                     for(sop = setOfPrim.begin(); sop != setOfPrim.end();sop++)
 86                     {
 87                               cout<<*sop<<" ";
 88                     }
 89                     cout<<"\nThe set of not prim:\n";
 90                     for(oop = outOfPrim.begin(); oop != outOfPrim.end();oop++)
 91                     {
 92                               cout<<*oop<<" ";
 93                     }
 94                     cout<<endl;
 95 
 96                     for(it = result.begin();it!=result.end();it++)
 97                     {
 98 
 99                               cout<<"("<<(*it).first<<","<<(*it).second<<")";
100                     }
101                     cout<<endl<<endl;
102           }
103 }
104 
105 
106 int main()
107 {
108           int n,d;
109           cin>>n>>d;
110           for(int i = 0;i<d;i++)
111           {
112                     int t,s,w;
113                     cin>>t>>s>>w;
114                     eg[t].push_back(make_pair(s,w));
115                     eg[s].push_back(make_pair(t,w));
116           }
117           prim(n,d);
118 
119 
120 
121 }
122 /*
123 6 8
124 0 1 2
125 0 3 4
126 1 4 4
127 2 0 5
128 2 5 2
129 3 4 3
130 3 5 7
131 5 4 3
132 */

 

最小生成树(prim)

原文:http://www.cnblogs.com/qlky/p/4987190.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!