以下图为例介绍Prim算法的执行过程。
![](http://img.51nod.com/upload/000FBEC5/08D26D9C84A3F3E60000000000000015.png)
![](http://img.51nod.com/upload/000FBEC5/08D26D9C6F360BB40000000000000014.png)
选中边AF , V = {A, F}, E = {(A,F)}
![](http://img.51nod.com/upload/000FBEC5/08D26D9C9254B3B60000000000000016.png)
选中边FB, V = {A, F, B}, E = {(A,F), (F,B)}
![](http://img.51nod.com/upload/000FBEC5/08D26D9CAE583E120000000000000017.png)
选中边BD, V = {A, B, F, D}, E = {(A,F), (F,B), (B,D)}
![](http://img.51nod.com/upload/000FBEC5/08D26D9CBD43E9850000000000000018.png)
选中边DE, V = {A, B, F, D, E}, E = {(A,F), (F,B), (B,D), (D,E)}
![](http://img.51nod.com/upload/000FBEC5/08D26D9CC894A92B0000000000000019.png)
选中边BC, V = {A, B, F, D, E, c}, E = {(A,F), (F,B), (B,D), (D,E), (B,C)}, 算法结束
以上内容引用51nod教程,觉得通俗易懂。
感觉和dijstra差不多,不过prim是随便拉一个点开始,搜它相连的路,放到优先队列里,标记一下走过的点,直至所有的点都被标记过,记录从队列里出来的权值,所有点走过跳出。
输入
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
输出
输出最小生成树的所有边的权值之和。
输入示例
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8
输出示例
37
#include<iostream> #include<cstdio> #include<vector> #include<functional> #include<queue> #include<cstring> using namespace std; struct node{ int place; int value; friend bool operator < (node n1,node n2){ if(n1.value == n2.value) return n1.place > n2.place; else return n1.value > n2.value; } }; struct edge{ int next; int to; int w; }; int head[1005]; int ii; vector<edge>vec; void add(int u,int v,int w){ struct edge e; e.to=v; e.w=w; e.next=head[u]; head[u]=ii++; vec.push_back(e); } int main(){ int m,n,s,e,w; int i; int visit[1005]; long long sum; while(scanf("%d%d",&n,&m)!=EOF){ memset(head,-1,sizeof(head)); memset(visit,0,sizeof(visit)); vec.clear(); ii=0; for(i=0;i<m;i++){ scanf("%d%d%d",&s,&e,&w); add(s,e,w); add(e,s,w); }/* for(vector<edge>::iterator it=vec.begin();it!=vec.end();it++) printf("%d %d %d\n",it->to,it->next,it->w); */ priority_queue<node>qn; while(!qn.empty()){ qn.pop(); } int j; node D,d; D.place=vec[head[s]].to; D.value=vec[head[s]].w; j=vec[head[s]].next; qn.push(D); visit[s]=1; while(j != -1){ D.place=vec[j].to; D.value=vec[j].w; j=vec[j].next; qn.push(D); } int ans=1; sum=0; while(!qn.empty()){ D=qn.top(); qn.pop(); if(!visit[D.place]){ visit[D.place]=1; sum+=D.value; ans++; } else continue; if(ans == n) { printf("%lld\n",sum); break; } j=head[D.place]; while(j != -1){ d.place=vec[j].to; d.value=vec[j].w; j=vec[j].next; if(!visit[d.place]){ qn.push(d); } } } } return 0; }