最小生成树算法模板
包含Kruskal和prim模板

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define maxn 2999
//kruskal 算法 贪心的求出最小生成树
struct node
{
    int u,v,w;
};//为了方便排序,建立一个结构体来存储边的关系
node e[maxn];
int n,m,sum=0,num=0,f[maxn+3];//f[]为并查集数组
//快排原函数
void quicksort(int left,int right)
{
    int i,j;
    if(left>right)
    return;
    i = left;
    j = right;
    while(i!=j)
    {
        while(e[j].w>=e[left].w&&i<j)
        {
        j--;
        }//先从右边找到一个比基准数小的
        while(e[i].w<+e[left].w&&i<j)
        {
            i++;
        }
        if(i<j)
        {
            swap(e[i],e[j]);
        }
    }
    swap(e[i],e[left]);
    quicksort(left,i-1);
    quicksort(i+1,right);
    return ;
}
int getf(int t)//递归找爹函数
{
    if(f[t]==t)
    return t;
    else
    {
        f[t] = getf(f[t]);//途中路径压缩
        return f[t];
    }
}
int amerge(int v,int u)//并查集合并子集函数,此处增加了判断两个点是否在同一个集合的功能
{
    int t1 = getf(v);
    int t2 = getf(u);
    if(t1!=t2)
    {
        f[t2] = t1;
        return 1;
    }
    return 0;
}
//在判断此边是否联通时,假如尚未联通则联通此边,直到满足cout == n-1即选用了N-1条边为止
//排序算法借鉴了贪心思想
int main()
{
int i;
while(~scanf("%d%d",&n,&m))
{
    for(i=1;i<=m;i++)//依次读入各边
    scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    quicksort(1,m);//按照边长(权值)依次排序
    for(i=1;i<=n;i++)
    {
    f[i] = i;
    }
    num = 0,sum = 0;
    //核心部分
    for(i=1;i<=m;i++)
    {
        if(amerge(e[i].u,e[i].v))//如果两个顶点尚未联通,则选用这条边
        {
            num++;
            sum+=e[i].w;
        }
        if(num==n-1)
        {
        break;
        }
    }
    printf("%d\n",sum);

}
return 0;
}

模板2:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define inf 99999999
#define maxn 2002
//Prim算法模板
int e[maxn][maxn],book[maxn],dis[maxn],n,m,t1,t2,t3;
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i==j)
                e[i][j]=0;
                else
                e[i][j]= inf;
            }
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&t1,&t2,&t3);
            e[t1][t2] = t3;
            e[t2][t1] = t3;
        }
        for(int i=1;i<=n;i++)
        {
            book[i] = 0;
            dis[i] = e[1][i];
        }
        int count = 0,sum = 0,min,j;
        book[1] = 1;//标记该点是否已经在生成树中
        count++;
        while(count<n)
        {
            min = inf;
            for(int i=1;i<=n;i++)
            {
                if(book[i]==0&&dis[i]<min)
                {
                    min = dis[i];
                    j = i;
                }
            }//从数组dis中找到离生成树最近的顶点,并加入生成树中
            book[j] = 1;
            count++;
            sum+=dis[j];//数组dis表示生成树到各个顶点的距离
            for(int k=1;k<=n;k++)//以J为中间点,更新生成树到每一个顶点的距离
            {
                if(book[k]==0&&dis[k]>e[j][k])
                dis[k] = e[j][k];//此处的松弛操作更改的是中间点到每个点(假如从该点到其他顶点更小的话则更新)
            }
        }
        //由于该算法是层层递推覆盖所以会取得最佳效果
        printf("%d\n",sum);
    }
    return 0;
}