Prim算法:N个顶点的图的最小生成树有N个顶点,N-1条边.
思想:分两个点集 S,U (S+U=V全部顶点) S中存放已经选入最小生成树的顶点, 开始任选一点放入S,遍历一下U,同时用一个数组Assist[505]来记录结果 找出和S中第一个点权值最小的点vi,把Assist[i-1]置零,表示已经被选入生成树.用vi遍历U中的点,同样找出U中的点和S中的点的权值最小的点.同时更新数组Assist[505];其记录着前i次的遍历结果的最小值.....例如U中的一个点v5 S中有v1 v2,其中D(v1,v5)=5,D(v2,v5)=3;则Assist[v5]=3; 本次从U中找出一个点v7 if(D(v7,v5)<3)则更新其值..
代码:
#include<cstdio>
int Assist[505];
int f[505][505];
int main()
{
int T,v,e,a,b,c,t,m,z,min,mx,sum;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&v,&e);
for(int i=1;i<=v;i++)
for(int j=i;j<=v;j++) f[j][i]=f[i][j]=1<<30;
while(e--)
{scanf("%d%d%d",&a,&b,&c);f[a][b]=f[b][a]=c;}
mx=0,sum=0;
m=1<<30;
for(int i=0;i<v;i++) {Assist[i]=f[1][i+1];scanf("%d",&z);if(z<m) m=z;}
t=v-1;
while(t--)
{
min=10000;
for(int i=1;i<v;i++)
if(Assist[i]&&(Assist[i]<min)) {min=Assist[i];mx=i;}
sum+=min;
Assist[mx]=0;
for(int i=1;i<v;i++) if(f[mx+1][i+1]<Assist[i]) Assist[i]=f[mx+1][i+1];
}
printf("%d\n",sum+m);
}
}