Prim算法:
    从一个节点出发, 每次找到连接的边, 找到最小权重的边, 将边连接的节点加入集合, 找出集合中所有点连接的边, 在寻找最小边, 知道所有点都被找到.
    将图存储在邻接矩阵中.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 0x3fffffff;
const int maxn = 10001;
int n, m;

int graph[maxn][maxn];  //将图存储在邻接矩阵中
int lowcost[maxn];      //记录邻接点的最短边
int visit[maxn];        //标记

void readin(){
    scanf("%d%d", &n, &m);
    int a, b, c;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            graph[i][j] = INF;
    for(int i = 1; i <= m; ++i){
        scanf("%d%d%d", &a, &b, &c);
        graph[a][b] = c;
        graph[b][a] = c;
    }
}

void init(int start){
    for(int i = 1; i <= n; ++i){
        lowcost[i] = graph[start][i];
        visit[i] = 0;
    }
}

int prim(int start)
{
    int ans = 0;
    int min;
    init(start);

    visit[start] = 1;

    for(int i = 1; i <= n; ++i){
        min = INF;
        int flag = -1;
        for(int j = 1; j <= n; ++j){        //找到最小值
            if(!visit[j] && min > lowcost[j]){
                min = lowcost[j];
                flag = j;
            }
        }

        if(flag != -1){
            cout << min <<endl;
            visit[flag] = 1;
            ans += min;                     //权值叠加

            for(int j = 1; j <= n; ++j){        //更新lowcost
                if(!visit[j] && graph[flag][j] < lowcost[j]){
                    lowcost[j] = graph[flag][j];
                }
            }
        }
    }
    return ans;
}
int main()
{
    readin();
    int ans = prim(1);
    cout << ans <<endl;
    return 0;
}
/*
5 6
1 2 1
2 3 2
1 3 2
1 4 3
4 3 5
4 5 3
*/