最小生成树之prime算法

介绍

最小生成树:无向图中,所有边权之和最小的树。

思想:

prime算法与Dijisktra算法思想相同,只是prime算法用一个集合存放已访问的结点,即构成最小生成树的顶点,而数组 d [ ] 则表示顶点到集合的最短距离。

实现

1.邻接矩阵法

const int maxn=100;
const int INF=1000000000;
int G[maxn][maxn];
bool isin[maxn]={false};
int dis[maxn];
int num;

int prime(){
    int sum=0;
    fill(dis,dis+maxn,INF);
    dis[0]=0;//从0号结点开始
    for(int i=0;i<num;i++){
        int m=-1,mv=INF;
        //开放结点
        for(int j=0;j<num;j++){
            if(isin[j]==false&&dis[j]<mv){
                m=j;
                mv=dis[j];
            }
        }
        if(m==-1) return-1;//不连通返回-1
        isin[m]=true;
        sum+=dis[m];//求最小路径之和
        //更新结点
        for(int k=0;k<num;k++){
            if(isin[k]==false&&G[m][k]!=INF&&G[m][k]<dis[k])
            dis[k]=G[m][k];//dis[]表示两结点间的最小距离,而非到根结点的距离
        }
    }
    return sum;
}

2.邻接表法

const int maxn=100;
const int INF=1000000000;
struct node{
    int v;
    int value;
};
vector<node> table[maxn];
bool isin[maxn]={false};
int dis[maxn];
int num;

int prime(){
    int sum=0;
    fill(dis,dis+maxn,INF);
    dis[0]=0;//从0号结点开始
    for(int i=0;i<num;i++){
        int m=-1,mv=INF;
        //开放结点
        for(int j=0;j<num;j++){
            if(isin[j]==false&&dis[j]<mv){
                m=j;
                mv=dis[j];
            }
        }
        if(m==-1) return -1;
        isin[m]=true;
        sum+=dis[m];//求最小路径之和
        //比较结点
        for(int k=0;k<table[i].size();k++){
            int v=table[i][k].v;//得到结点下标
            if(isin[v]==false&&table[i][k].value<dis[v])
            dis[v]=table[i][k].value;//dis[]表示两结点间的最小距离,而非到根结点的距离
        }
    }
    return sum;
}

简单应用

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100;
const int INF=1000000000;
int num,road;
int G[maxn][maxn];
bool isin[maxn]={false};
int path[maxn],sum=0;

void prime(){
    fill(path,path+maxn,INF);
    path[0]=0;
    for(int i=0;i<num;i++){
        int m=-1,mv=INF;
        for(int j=0;j<num;j++){
            if(isin[j]==false&&path[j]<mv){
                m=j;
                mv=path[j];
            }
        }
        if(m==-1) return;
        isin[m]=true;
        sum+=path[m];
        for(int k=0;k<num;k++){
            if(isin[k]==false&&G[m][k]!=INF&&G[m][k]<path[k])
            path[k]=G[m][k];
        }
    }
}

int main(){
    int v1,v2;
    fill(G[0],G[0]+maxn*maxn,INF);
    cin>>num>>road;
    for(int i=0;i<road;i++){
        cin>>v1>>v2>>G[v1][v2];
        G[v2][v1]=G[v1][v2];
    }
    prime();
    cout<<sum<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值