图论-最小生成树算法

本文详细介绍了两种经典的最小生成树算法:Prim算法和Kruskal算法。Prim算法通过迭代选择距离最近的顶点来逐步构建生成树,而Kruskal算法则是按边的权重从小到大排序后依次加入不构成环的边来构建生成树。
摘要由CSDN通过智能技术生成

Prim算法

void prime()  
{  
    int i,j,min,mindis=0,next;  
    memset(tree,0,sizeof(tree));  
    for(i=1;i<=point;i++)  
    {  
        lowdis[i]=map[begin][i];//用lowdis[]数组记录下从起点到剩下所有点的距离  
    }  
    tree[begin]=1;//标记起点(即最小生成树中的点)  
    for(i=1;i<point;i++)  
    {  
        min=INF;  
        for(j=1;j<=point;j++)  
        {  
            if(!tree[j]&&min>lowdis[j])  
            {  
                min=lowdis[j];//求出从当前起点到其余所有点的距离中最短的  
                next=j;  
            }  
        }  
        mindis+=min;//记录下整条最小树的长度  
        tree[next]=1;  
        for(j=1;j<=point;j++)  
        {  
            if(!tree[j]&&lowdis[j]>map[next][j])  
            lowdis[j]=map[next][j];//更新lowdis[]数组  
        }  
    }  
    printf("%d\n",mindis);  
}

kruskal算法

#include<iostream>  
#include<cstdio>  
#include<string.h>  
#include<algorithm>  
#include<fstream>  
using namespace std;  
  
const int MAXN=505;//最大点数  
const int MAXM=250005;//最大边数  
int F[MAXN];//并查集使用  
  
struct Edge  
{  
    int u,v,w;  
}edge[MAXM];//储存边的信息,包括起点/终点/权值  
  
int tol;//边数,加边前赋值为0  
  
void addedge(int u,int v,int w)  
{  
    edge[tol].u=u;  
    edge[tol].v=v;  
    edge[tol++].w=w;  
}  
  
bool cmp(Edge a,Edge b)//排序函数,边按照权值从小到大排序  
{  
    return a.w<b.w;  
}  
  
int Find(int x)  
{  
    if(F[x]==-1)  
        return x;  
    else  
        return F[x]=Find(F[x]);  
}  
  
int Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1  
{  
    memset(F,-1,sizeof(F));  
    sort(edge,edge+tol,cmp);  
    int cnt=0;//计算加入的边数  
    int ans=0;  
    for(int i=0;i<tol;i++)  
    {  
        int u=edge[i].u;  
        int v=edge[i].v;  
        int w=edge[i].w;  
        int t1=Find(u);  
        int t2=Find(v);  
        if(t1!=t2)  
        {  
            ans+=w;  
            F[t1]=t2;  
            cnt++;  
        }  
        if(cnt==n-1)  
            break;  
    }  
    if(cnt<n-1)  
        return -1;//不连通  
    else  
        return ans;  
}  
  
int main()  
{  
    //freopen("in.txt","r",stdin);  
    int T;  
    cin>>T;  
    int n;  
    int c;  
    while(T--)  
    {  
        cin>>n;  
        tol=0;  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=1;j<=n;j++)  
            {  
                cin>>c;  
                addedge(i,j,c);  
            }  
        }  
        cout<<Kruskal(n)<<endl;  
    }  
    return 0;  
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值