最小生成树模板

Kruskal
思想:贪心+并查集

#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2e5+10;
typedef long long ll;
int n,m;
struct edge
{
    int x,y,z;
}edges[M];

int father[N];

void init()
{   
    for(int i=0;i<n;i++)father[i]=i;
}

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

bool join(int x,int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx!=fy)
    {
        father[fx]=fy;
        return true;
    }
    else return false;

}


bool cmp(edge  a,edge b)
{
    return a.z<b.z;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    init();
    for(int i=0;i<m;i++)
    {
        cin>>edges[i].x>>edges[i].y>>edges[i].z;
    }
    sort(edges,edges+m,cmp);
    // for(int i=0;i<m;i++)
    // {
    //     cout<<edges[i].x<<' '<<edges[i].y<<' '<<edges[i].z<<endl;
    // }
    int ans=0;
    int cnt=0;
    for(int i=0;i<m;i++)
    {
        if(join(edges[i].x,edges[i].y))
        {
            cnt++;
            ans+=edges[i].z;
        }
    }

    if(cnt!=n-1)cout<<"orz"<<endl;
    else cout<<ans<<endl;
    return 0;
}

Prim

#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
typedef long long ll;
int n,m;
bool vis[N];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    memset(vis,false,sizeof(vis));
    vector<vector<pair<int,int>>>edges(n+1);
    for(int i=0;i<m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        edges[u].push_back(make_pair(v,w));
        edges[v].push_back(make_pair(u,w));
    }

    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>heap;
    vis[1]=true;
    ll ans=0;
    int cnt=1;

    for(auto edge : edges[1])
    {
        heap.push({edge.second,edge.first});
    }

    while(!heap.empty())
    {
        int cost = heap.top().first;
        int node = heap.top().second;
        heap.pop();
        if(vis[node])continue;
        ans+=cost;
        vis[node]=true;
        cnt++;

        for(auto edge:edges[node])
        {
            int w = edge.second;
            int next = edge.first;
            if(!vis[next])heap.push({w,next});
        }
    }

    if(cnt!=n)cout<<"orz"<<endl;
    else cout<<ans<<endl;
    return 0;
}

Prim算法优化版
时间复杂度O(n + m) + O((m+n) * log n)

#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=4e5+10;
typedef long long ll;
int n,m;
int head[N];
int nt[M];
int to[M];
int heap[N][2];

int where[N];
int weight[M];
int cnt=0;
int cnt2=1;
int hsz=0;
int u,v,w;

void addEdge(int u,int v,int w)
{
    nt[cnt2] = head[u];
    to[cnt2] = v;
    weight[cnt2]=w;
    head[u]=cnt2++;
}

bool isEmpty()
{
    return hsz==0;
}

void heapInsert(int i)
{
    while(heap[i][1]<heap[(i-1)/2][1])
    {
        swap(heap[i],heap[(i-1)/2]);
        swap(where[heap[i][0]],where[heap[(i-1)/2][0]]);
        i = (i-1)/2;
    }
}



void update(int i)
{
    int v = to[i];
    int w = weight[i];
    if(where[v]==-1)
    {
        heap[hsz][0]=v;
        heap[hsz][1]=w;
        where[v] = hsz++;
        heapInsert(where[v]);
    }
    else if(where[v]>=0)
    {
        heap[where[v]][1]=min(heap[where[v]][1],w);
        heapInsert(where[v]);
    }
}

void heapify(int i)
{
    int l=i*2+1;
    while(l<hsz)
    {
        int best = l+1 < hsz && heap[l+1][1]<heap[l][1] ? l+1:l;
        best = heap[best][1] < heap[i][1] ? best : i;
        if(best == i)
        {
            break;
        }
        swap(heap[best],heap[i]);
        swap(where[heap[best][0]],where[heap[i][0]]);
        i = best;
        l = i * 2 + 1;
    }


}



void pop()
{
    u = heap[0][0];
    w = heap[0][1];
    swap(heap[0],heap[--hsz]);
    swap(where[heap[0][0]],where[heap[hsz][0]]);
    heapify(0);
    where[u]=-2;
    cnt++;
    
}


int prim()
{
    cnt=1;
    where[1]=-2;
    for(int i=head[1];i>0;i=nt[i])
    {
        update(i);
    }
    int ans=0;
    while(!isEmpty())
    {
        pop();
        ans+=w;
        for(int i=head[u];i>0;i=nt[i])
        {
            update(i);
        }
    }
    return ans;

}


int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    memset(where,-1,sizeof(where));
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        addEdge(u,v,w);
        addEdge(v,u,w);
    }

    int ans = prim();
    if(cnt==n)cout<<ans<<endl;
    else cout<<"orz"<<endl;

    return 0;
}
posted @ 2025-07-17 17:11  屈臣  阅读(5)  评论(0)    收藏  举报