无向图的最小生成树

最小生成树

在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。 

 

求最小生成树的两种方法

 

1.Kruskal算法

此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。

2.Prim算法

此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。

 

 

 第二种方法来实现代码,如下:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int min;int n,m;
int fan[10005][10005];
int vis[10005],low[10005]; 
int ss(){
    int min,pos,sum=0;
    memset(vis,0,sizeof(vis));
    pos=1;
    vis[1]=1;
    for(int i=1;i<=n;i++){  
        if(i!=pos)
        low[i]=fan[pos][i];  //此时的low[i]中找到了从点1开始到其他能联通边的权值 
    }
    for(int i=1;i<n;i++){  //共n-1条边相加 
        min=9999999;    
        for(int j=1;j<=n;j++){ 
           //按权值从小到大的顺序找边 
               if(!vis[j]&&low[j]<min){
        //如果这个点没有被联通
               min=low[j];
               pos=j; 
              }
       }
        sum+=min;  //将权值大小依次相加。
        vis[pos]=1;//标记一下表示此点已经和点1联通 
        for(int j=1;j<=n;j++){
            //此时为找到和上一个点已经连通过的点,它和它能联通的点的边的权值 
            if(!vis[j]&&low[j]>fan[pos][j]){
                low[j]=fan[pos][j];
            } 
        } 
   }
   return sum;
}
int main(){
    while(cin>>n>>m){
        int a,b,c;
    memset(fan,999999,sizeof(fan));
    for(int i=1;i<=m;i++){
        cin>>a>>b>>c;
        if(fan[a][b]>c) {
            //防重边 
             fan[a][b]=c;
            fan[b][a]=c; 
        }
    }
    cout<<ss()<<endl;
    }
    
    return 0;
}
View Code

 

 

posted @ 2022-11-03 21:28  kuailest  阅读(174)  评论(0编辑  收藏  举报