最小生成树

Prim

基于优先队列

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

#define INF 1e9
const int MAXN = 200005;
int n, m, ans;
struct edge
{
    int v, w;
};
struct node
{
    int dis, u;
    bool operator>(const node &a) const
    {
        return dis > a.dis;
    }
};
vector<edge> e[MAXN];
int d[MAXN], vis[MAXN];

bool prim(int s)
{
    memset(vis, 0, sizeof(vis));
    priority_queue<node, vector<node>, greater<node>> q;
    int cnt = 0;
    for (int i = 0; i <= n; i++)
        d[i] = INF;
    d[s] = 0;
    q.push({0, s});
    while (!q.empty())
    {
        int u = q.top().u;
        q.pop();
        if (vis[u])
            continue;
        vis[u] = 1; // 标记出圈
        ans += d[u];
        cnt++;
        for (auto ed : e[u])
        {
            int v = ed.v, w = ed.w;
            if (d[v] > w)
            {
                d[v] = w; // 到圈外任意一点的最小距离
                q.push({d[v], v});
            }
        }
    }
    return cnt == n;
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int u, v, w;
        cin >> u >> v >> w;
        e[u].push_back({v, w});
        e[v].push_back({u, w});
    }
    if (prim(1))
        cout << ans;
    else
        cout << "orz";
    return 0;
}

Kruskal

基于并查集

#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 200005;
struct edge
{
    int u, v, w;
    bool operator<(const edge &t) const
    {
        return w < t.w;
    }
} e[MAXN];
int fa[MAXN];
int ans, n, m;

int find(int x)
{
    return fa[x] == x ? x : (fa[x] = find(fa[x]));
}
bool kruskal()
{
    int cnt = 0;
    sort(e, e + m);
    for (int i = 1; i <= n; i++)
        fa[i] = i;
    for (int i = 0; i < m; i++)
    {
        int x = find(e[i].u);
        int y = find(e[i].v);
        if (x != y)
        {
            fa[x] = y;
            ans += e[i].w;
            cnt++;
        }
    }
    return cnt == n - 1;
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; i++)
        cin >> e[i].u >> e[i].v >> e[i].w;
    if (kruskal())
        cout << ans;
    else
        cout << "orz";
    return 0;
}

P3366 [模板]最小生成树

posted @ 2025-07-07 11:50  张诗羽  阅读(12)  评论(0)    收藏  举报