图的最小生成树——Prim算法
Prim算法
Prim算法求最小生成树是采取蓝白点的思想,白点代表已经加入最小生成树的点,蓝点表示未加入最小生成树的点。
进行n次循环,每次循环把一个蓝点变为白点,该蓝点应该是与白点相连的最小边权的是当前蓝点中最小的。这样就相当于向生成树中添加了n-1次最小的边,最后得到的一定是最小生成树。
1 #include<cstdio> 2 #include<cstring> 3 #define N 42000 4 using namespace std; 5 int next[N],to[N],dis[N],num,head[N],n,m,a,b,c,minn[N]; 6 bool u[N]; 7 void add(int false_from,int false_to,int false_dis){ 8 next[++num]=head[false_from]; 9 to[num]=false_to; 10 dis[num]=false_dis; 11 head[false_from]=num; 12 } 13 int main(){ 14 scanf("%d%d",&n,&m); 15 for(int i=1;i<=m;++i){ 16 scanf("%d%d%d",&a,&b,&c); 17 add(a,b,c); 18 add(b,a,c); 19 } 20 memset(minn,0x7f,sizeof(minn)); 21 minn[1]=0; 22 memset(u,1,sizeof(u)); 23 for(int i=1;i<=n;++i){ 24 int k=0; 25 for(int j=1;j<=n;j++) 26 if(u[j]&&(minn[j]<minn[k])) 27 k=j; 28 u[k]=0; 29 for(int j=head[k];j;j=next[j]) 30 if(u[to[j]]&&(dis[j]<minn[to[j]])) 31 minn[to[j]]=dis[j]; 32 } 33 int total=0; 34 for(int i=1;i<=n;++i){ 35 total+=minn[i]; 36 printf("%d ",minn[i]); 37 } 38 printf("\n%d",total); 39 return 0; 40 }