挖坑(kruskal/prim)


对于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;
}
posted @ 2025-03-07 22:53  郭轩均  阅读(25)  评论(0)    收藏  举报