最小生成树裸题,给出n个点的坐标,求MST的权值总和,用prim实现
#include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> #define INF 100000000.0 #define N 110 using namespace std; double x[N],y[N],dis[N][N],lowcoat[N]; bool vis[N]; int n; double DIS(int i , int j) { return sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ) ; } int main() { int i,j,k,nn; double min,SUM; while(scanf("%d",&n)!=EOF) { if(!n) break; for(i=1; i<=n; i++) scanf("%lf%lf",&x[i],&y[i]); for(i=1; i<=n; i++) for(j=1; j<=n; j++) dis[i][j]=dis[j][i]=DIS(i,j); //用prim算法因为没有给出边集数组而是给出了顶点用prim算法更合理 memset(vis,0,sizeof(vis)); for(i=1; i<=n; i++) lowcoat[i]=dis[1][i]; lowcoat[1]=0; vis[1]=1; SUM=0; for(nn=1; nn<n; nn++) //个数,还有纳入n-1个点 { min=INF; k=1; for(i=2; i<=n; i++) if(!vis[i] && lowcoat[i] < min) { min=lowcoat[i]; k=i; } vis[k]=1; lowcoat[k]=0; SUM+=min; for(i=2; i<=n; i++) //更新所有的边 if(!vis[i] && dis[k][i] < lowcoat[i]) lowcoat[i]=dis[k][i]; } printf("%.2f\n",SUM); } return 0; }