prim算法

prim算法其实和dijkstra算法在实现上基本上一样,也很容易理解。

 

prim算法的基本思想:

取图中任意一个顶点 v 作为生成树的根,之后往生成树上添加新的顶点 w。在添加的顶点 w 和已经在生成树上的顶点v 之间必定存在一条边,并且该边的权值在所有连通顶点 v 和 w 之间的边中取值最小。之后继续往生成树上添加顶点,直至生成树上含有 n个顶点为止。

 

在生成树的构造过程中,图中 n 个顶点分属两个集合:已落在生成树上的顶点集 U 和尚未落在生成树上的顶点集V-U ,则应在所有连通U中顶点和V-U中顶点的边中选取权值最小的边。

 

注意:prim算法是用于求无向图的最小生成树,但是偶不想画图,故依然拿了前面的有向图,但是大家可以将箭头去掉,全当无向图。

 

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int MAXNUM=101;
 5 
 6 //9*9
 7 int MAP[MAXNUM][MAXNUM]={
 8     {INT_MAX,      2,INT_MAX,INT_MAX,INT_MAX,      9,     15,INT_MAX,INT_MAX},
 9     {      2,INT_MAX,      4,INT_MAX,INT_MAX,INT_MAX,      6,INT_MAX,INT_MAX},
10     {INT_MAX,      4,INT_MAX,      2,INT_MAX,INT_MAX,INT_MAX,INT_MAX,     15},
11     {INT_MAX,INT_MAX,      2,INT_MAX,      1,INT_MAX,INT_MAX,INT_MAX,      1},
12     {INT_MAX,INT_MAX,INT_MAX,      1,INT_MAX,      6,INT_MAX,      3,INT_MAX},
13     {      9,INT_MAX,INT_MAX,INT_MAX,      6,INT_MAX,INT_MAX,     11,INT_MAX},
14     {     15,      6,INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX,     15,      2},
15     {INT_MAX,INT_MAX,INT_MAX,INT_MAX,      3,     11,     15,INT_MAX,      4},
16     {INT_MAX,INT_MAX,     15,      1,INT_MAX,INT_MAX,      2,      4,INT_MAX}
17 };
18 
19 int adjvex[MAXNUM];        //adjvex[i]=j表示j到i的路径
20 int lowcost[MAXNUM];    //lowcost[i]表示U集中顶点的顶点到V-U集中的i顶点的最短路径(一条边)
21 
22 void prim(int s,int n)
23 {
24     int i;
25     bool mark[MAXNUM]={false};        //mark[i]==true表示i顶点属于U集
26     for(i=0;i<n;++i)
27     {
28         adjvex[i]=s;    //表示s到i的路径
29         lowcost[i]=MAP[s][i];
30     }
31     mark[s]=true;        //源点s属于U集
32     for(i=2;i<n;++i)    //循环n-2次就可以完成
33     {
34         int index=s,lowest=INT_MAX;
35         int j;
36         //在所有U集到V-U集的边中找出最小的一条
37         //mark[0~n]==false的边中找出
38         for(j=0;j<n;++j)
39         {
40             if(mark[j]==false&&lowcost[j]<lowest)
41             {
42                 lowest=lowcost[j];
43                 index=j;
44             }
45         }
46         mark[index]=true;    //加入index顶点到U集
47         //用新加入U集的顶点来更新lowcost的值
48         //既更新U集到V-U集边的值(mark[j]==false)
49         for(j=0;j<n;++j)
50             if(mark[j]==false&&MAP[index][j]<lowcost[j])
51             {
52                 lowcost[j]=MAP[index][j];
53                 adjvex[j]=index;    //记录到j的路径中,j的前驱结点是index
54             }
55     }
56 }
57 
58 
59 void reverse(int a[],int n)
60 {
61     for(int i=0,j=n-1;i<j;++i,--j)
62         swap(a[i],a[j]);
63 }
64 
65 int getpath(int a[],int i,int j)
66 {
67     int count=1;
68     a[0]=j;
69     while(i!=j)
70         j=a[count++]=adjvex[j];
71     reverse(a,count);
72     return count;
73 }
74 
75 int main()
76 {
77     int a[MAXNUM];
78     prim(0,9);
79     int i;
80     for(i=1;i<9;++i)
81     {
82         cout<<"a到"<<char(i+'a')<<"的路径为:";
83         int length=getpath(a,0,i);
84         for(int j=0;j<length;++j)
85             cout<<char(a[j]+'a')<<' ';
86         cout<<endl;
87     }
88     int s=0;
89     for(i=1;i<9;++i)
90         s+=lowcost[i];
91     cout<<"最小生成树的权值和为:";
92     cout<<s<<endl;
93     return 0;
94 }

 

 

 

prim算法和dijkstra算法的实现简直就是一模一样,除了数组有些不同,也很明显他们的效率很大程度取决于查找最小值的效率。

下为用队列实现的prim算法,和dijkstra的也一样,哈哈

 

 1 void prim(int s,int n)
 2 {
 3     int q[MAXNUM],qf=0,ql=0;    //建立一个队列用来存储未加入U集的顶点的下标
 4     int i;
 5     for(i=0;i<n;++i)
 6     {
 7         lowcost[i]=MAP[s][i];
 8         adjvex[i]=s;
 9         if(i!=s)    //将V-U集中的顶点的下标加入到队列q中
10             q[ql++]=i;
11     }
12     while(qf<ql-1)    //循环n-2次就ok
13     {
14         int index_min=qf;
15         int j;
16         //q[qf~ql-1]指向的都是V-U集的顶点,找出lowcost最小
17         for(j=qf+1;j<ql;++j)
18             if(lowcost[q[j]]<lowcost[q[index_min]])
19                 index_min=j;
20         swap(q[index_min],q[qf]);    //始终保持q[qf]指向U到V-U中最小的边
21         for(j=qf+1;j<ql;++j)    //用新加入U集的顶点来更新U到V-U的边
22             if(MAP[q[qf]][q[j]]<lowcost[q[j]])
23             {
24                 lowcost[q[j]]=MAP[q[qf]][q[j]];
25                 adjvex[q[j]]=q[qf];
26             }
27         ++qf;    //注意
28     }
29 }

 

posted on 2011-02-01 16:46  bug睡的略爽  阅读(226)  评论(0编辑  收藏  举报

导航