prim解决最小生成树问题

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
using namespace std;

const int MAXV = 1000;//最大顶点数
const int INF = 1000000000;

//n为顶点数
//MAXV为最大顶点数 
int n,m;
double G[MAXV][MAXV];
double d[MAXV];// 顶点到集合S的最短距离
bool vis[MAXV] = {false};//标记数组,vis[i] == true表示已访问

double prim()
{
    fill(d,d+MAXV,INF);
    d[0] = 0;//只有0号顶点到集合s的距离为0,其他全为INF
    double ans = 0;//存放最小生成树的边权之和
    
    //找n个点 
    for(int i=0;i<n;i++) 
    {
        int u = -1,MIN = INF;//u使d[u]最小,MIN存放该最小的d[u]
        
        //每次找一个到集合距离最小的点 
        for(int j = 0;j < n;j++)
        {
            if(vis[j] == false && d[j] < MIN)
            {
                u = j;
                
                MIN = d[j]; 
            }
         } 
         
         if( u== -1 )
         {
             return -1;
         } 
         
         //标记u为已访问 
         vis[u] = true;
         
         ans += d[u];
         
         for(int v=0;v < n;v++)
         {
             //如果v未访问,且u能到达v,并且以u为中转可以是v离集合更近 
             if(vis[v] == false && G[u][v] != INF && G[u][v] < d[v])
             {
                 d[v] = G[u][v] ;
            }
         }
    }
    
    return ans;
 } 
 
 struct point
 {
     int x;
     int y;
 };
 
 point p[MAXV];
 
 double getDis(point &a,point &b)
 {
     return sqrt( (a.x - b.x)*(a.x - b.x)  + (a.y - b.y)*(a.y - b.y));
 }
 
 int main()
 {
     cin >> n;
     
     
     for(int i=0;i<n;i++)
     {
         cin >> p[i].x;
        cin >> p[i].y;    
    }
     //初始化图G 
     fill(G[0],G[0] + MAXV * MAXV,INF);
     
     for(int i=0;i<m;i++) 
     {
         cin >> p[i].x;
         cin >> p[i].y;
    }
    
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            G[i][j] = getDis(p[i],p[j]);
        }
    }
     
     double ans = prim();
     
     printf("%.2f 
",ans);
     return 0;
 }
原文地址:https://www.cnblogs.com/xiaochi/p/10415314.html