图的最小生成树——Prim算法

时间:2022-01-05 12:35:15

Prim算法

Prim算法求最小生成树是采取蓝白点的思想,白点代表已经加入最小生成树的点,蓝点表示未加入最小生成树的点。

进行n次循环,每次循环把一个蓝点变为白点,该蓝点应该是与白点相连的最小边权的是当前蓝点中最小的。这样就相当于向生成树中添加了n-1次最小的边,最后得到的一定是最小生成树。

图的最小生成树——Prim算法图的最小生成树——Prim算法
 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 }
View Code