Minimum spanning tree-prim and kruskal algorithm

Topic: Portal

prim algorithm

Idea:
Use an array to record the minimum distance from each point to the set where the minimum spanning tree is located. Each time the point with the smallest distance is selected to join the set at that distance, and the point is used to update the distance of other points.

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 5010, M = 200010;
int g[N][N], res, n, m;
int dis[N]; // dis[i]:当前使得第i个点加入集合的最小距离
bool in[N]; // 记录当前点是否被加入集合

bool prim()
{
    
    
    memset(dis, 0x3f, sizeof dis);
    dis[1] = 0;

    for (int i = 1; i <= n; i++)
    {
    
    
        int t = -1;
        for(int j = 1; j <= n; j++)
            if(!in[j] && (t == -1 || dis[t] > dis[j])) t = j;

        if (dis[t] == 0x3f3f3f3f) return false; // 若所有未加入集合的点到集合的距离均为无穷大,则不存在最小生成树
        
        res += dis[t];
        in[t] = true;
    
        for(int j = 1; j <= n; j++)
            dis[j] = min(dis[j], g[t][j]);
    }

    return true;
}

int main()
{
    
    
    memset(g, 0x3f, sizeof g);
    cin >> n >> m;

    int x, y, z;
    for(int i = 0; i < m; i++)
    {
    
    
        cin >> x >> y >> z;
        g[y][x] = g[x][y] = min(g[x][y], z);
    }

    if(prim()) cout << res;
    else cout << "orz";
    
    return 0;
}

 

kruskal algorithm

Idea:
Sort all edges according to their weights from small to large, then traverse each edge, and use the combined search to determine whether the left and right endpoints of the edge belong to the same set. If they do not belong, the edge is the edge in the minimum spanning tree, and finally The sets where the left and right endpoints are located are merged.

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 5010, M = 200010;
int f[N];
int n, m;

struct edge
{
    
    
    int a, b, w;
    bool operator < (const edge & t)
    {
    
    
        return w < t.w;
    }
}edges[M];

inline int find(int x)
{
    
    
    if(x != f[x]) f[x] = find(f[x]);
    return f[x];
}

int main()
{
    
    
    cin >> n >> m;

    int x, y, z;
    for(int i = 0; i < m; i++)
    {
    
    
        cin >> x >> y >> z;
        edges[i] = {
    
    x, y, z};
    }

    sort(edges, edges+m);

    for (int i = 1; i <= n; i++) f[i] = i;

    int cnt = 0, ans = 0;

    for(int i = 0; i < m; i++)
    {
    
    
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        a = find(a), b = find(b);

        if( a!= b)
        {
    
    
            cnt++;
            ans += w;
            f[a] = b;
        }
    }
   
    if(cnt < n - 1) cout << "orz"; //仅当合并次数为n-1次,所有点才处于同集合中,否则最小生成树不存在
    else cout << ans;
    return 0;
}

Guess you like

Origin blog.csdn.net/PBomb/article/details/107756812