最小生成树模板题。
prim算法:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2*500000+10;
const int maxnn = 100000+10;
struct sy{
    int to;
    int next;
    int w;
} edge[maxn];
int head[maxn];
struct Node{
    int number;
    int w;
    bool operator < (const Node &n) const {
        return w>n.w;
    }
};
priority_queue<Node> pq;
bool vis[maxnn];
int cnt = 0;
int n, m;

void add_edge(int x, int y, int w)
{
    edge[++cnt].next = head[x];
    edge[cnt].to = y;
    edge[cnt].w = w;
    head[x] = cnt;
}
//普利姆算法,利用贪心的原理求最小生成树
int prim()
{
    int ans = 0;
    pq.push({1, 0});
    while (pq.size())
    {
        Node node = pq.top();
        pq.pop();
        int number = node.number;
        int w = node.w;
        if (vis[number]) continue;
        ans += w;
        vis[number] = true;
        //遍历这个点的其他边,找出没有遍历过的加入
        for (int i=head[number];i;i = edge[i].next)
        {
            int next = edge[i].to;
//             cout<<next<<" "<<edge[i].w<<endl;
            if (vis[next]) continue;
            pq.push({next, edge[i].w});
        }
    }
    return ans;
}

int main()
{
    int x, y ,w;
    cin>>n>>m;
    for (int i=1;i<=m;i++)
    {
        cin>>x>>y>>w;
        add_edge(x, y, w);
        add_edge(y, x, w);
    }
    int ans = prim();
    cout<<ans;
    return 0;
}
克鲁斯卡尔算法:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2*500000+10;
struct Node{
    int x, y, w;
} node[maxn];

bool comp(Node n1, Node n2)
{
    return n1.w<n2.w;
}
int fa[100000+10];
int n, m;

int find(int x)
{
    return fa[x]==0?x:fa[x] = find(fa[x]);
}


int main()
{
    cin>>n>>m;
    for (int i=1;i<=m;i++)
    {
        cin>>node[i].x>>node[i].y>>node[i].w;
    }
    sort(node+1, node+1+m, comp);
    int ans = 0;
    for (int i=1;i<=m;i++)
    {
        int x = node[i].x;
        int y = node[i].y;
        int rootx = find(x);
        int rooty = find(y);
        if (rootx==rooty) continue;
        ans += node[i].w;
        fa[rootx] = rooty;
    }
    cout<<ans<<endl;
    return 0;
}