对于prim算法
我们要更新一个点到一个已经在在树里的点的最小距离,作为答案,最开始要将起点加入优先队列,并且最开始要把d数组初始化为最大值
对于kruskal算法
我们需要用到并查集,对所有的边的边权进行排序,如果边的两个不在一个集合,就可以连接两点并让答案加上边权,如果两个点在统一个集合则不能连接,不然会成环,个人认为kruskal算法更简单
/*#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e5+5;
struct node{int id,dis;
};
int d[N];
vector<node>v[N];
bool operator<(node n1,node n2){return n1.dis>n2.dis;
}
int n,m;
int vis[N];
long long ans=0;
bool prim(){int cnt=0;priority_queue<node>q;memset(d,0x3f,sizeof(d));q.push({1,0});d[1]=0;while(!q.empty()){int u=q.top().id;q.pop();if(vis[u])continue;vis[u]=1;ans+=d[u];cnt++;for(int i=0;i<v[u].size();i++){//if(vis[v[u][i].id])continue;if(d[v[u][i].id]>v[u][i].dis){d[v[u][i].id]=v[u][i].dis;q.push({v[u][i].id,d[v[u][i].id]});}}}return cnt==n;
}
int main(){cin>>n>>m;while(m--){int a,b,x;cin>>a>>b>>x;v[a].push_back({b,x});v[b].push_back({a,x});}if(prim())cout<<ans;else cout<<"orz";return 0;
}*/
//kruskal
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=5*1e5+5;
int n,m;
struct edge{int x,y,z;//起点,终点,边权
}e[N];
int f[N];
void init(){for(int i=1;i<=n;i++)f[i]=i;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);
}
void unite(int x,int y){int rootx=find(x);int rooty=find(y);if(rootx!=rooty)f[rootx]=rooty;
}
bool cmp(edge e1,edge e2){return e1.z<e2.z;
}
signed main(){cin>>n>>m;init();for(int i=1;i<=m;i++){cin>>e[i].x>>e[i].y>>e[i].z;}sort(e+1,e+1+m,cmp);int ans=0;int cnt=0;for(int i=1;i<=m;i++){int rootx=find(e[i].x);int rooty=find(e[i].y);if(rootx==rooty)continue;else{ans+=e[i].z;cnt++;unite(e[i].x,e[i].y);if(cnt==n-1)break;}}if(cnt==n-1)cout<<ans;return 0;
}