图论-最小生成树

模板题:寻宝
1.克鲁斯卡尔(并查集)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef struct{
    int w,a,b;
}edge;
edge e[N];
bool cmp(edge a,edge b){
    return a.w<b.w;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int w,a,b;
        cin>>a>>b>>w;
        e[i]={w,a,b};
    }
    sort(e,e+m,cmp);
    int sum=0;
    vector<int> fa(n+1);
    for(int i=0;i<=n;i++)fa[i]=i;
    auto find=[&](auto &&find,int x)->int{
        if(fa[x]==x)return x;
        return fa[x]=find(find,fa[x]);
    };
    auto join=[&](int x,int y)->bool{
        int xx=find(find,x);
        int yy=find(find,y);
        if(xx==yy)return 1;
        fa[xx]=yy;
        return 0;
    };
    for(int i=0;i<m;i++){
        auto [w,a,b]=e[i];
        if(join(a,b)==0){
            sum+=w;
        }
    }
    cout<<sum<<'\n';
}
2.prim算法(堆优化版)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
vector<PII>v[N];
int dist[N];
int main()
{
    int n,m;
    cin>>n>>m;
    memset(dist,0x3f,sizeof(dist));
    for(int i=0;i<m;i++)
    {
        int v1,v2,val;
        cin>>v1>>v2>>val;
        v[v1].push_back({val,v2});
        v[v2].push_back({val,v1});
    }
    vector<int>vis(n+1);
    priority_queue<PII,vector<PII>,greater<PII>> q;
    q.push({0,1});
    int cnt=0;
    int sum=0;
    while(q.size()&&cnt<n){//n个点都包含了就退出
        auto [a,b]=q.top();
        q.pop();
        if(vis[b])continue;//一个点可能不止一次被放进队列
        vis[b]=1;//加入此点
        cnt++;
        sum+=a;
        for(auto [w,u]:v[b]){
            if(vis[u])continue;
            if(dist[u]<=w)continue;
            dist[u]=w;
            q.push({w,u});
        }
    }
    cout<<sum<<'\n';
}
posted @ 2026-01-23 17:59  spark_of_fire  阅读(2)  评论(0)    收藏  举报