几种最小生成树算法

来源:互联网 发布:淘宝开通购物号 编辑:程序博客网 时间:2024/05/16 06:03

Kruskal O(e * log e)

#define maxm        // 最大边数 #define maxn        // 最大顶点数 int u[maxm];        // 边的起点 int v[maxm];        //  终点 int w[maxm];        // 边权 int p[maxn];        // 并查 int r[maxm];        // 排序辅助数组 int n, m;int cmp(int i, int j) {    return w[i] < w[j];}int findp(int x) {    return p[x] == x ? x : p[x] = findp(p[x]);}int kruskal() {    int ans = 0;    int cnt = 0;    for (int i = 0; i < m; i++) {        r[i] = i;    }     for (int i = 0; i < n; i++) {        p[i] = i;    }    sort(r, r + m, cmp);    for (int i = 0; i < m; i++) {        int e = r[i], x = findp(u[e]), y = findp(v[e]);        if (x != y) {            p[x] = y;            ans += w[e];            cnt++;        }        if (cnt >= n - 1) {            break;        }    }    return ans;}

Prim O(v * v)

#define maxn #define inf int lc[maxn];           // 点到已选点集合中的点的最短路径长度 int d[maxn][maxn];      // 原图 int v[maxn];            // 已选标记 int n;                  // 总点数 int prim() {    int ans = 0;            memset(v, 0, sizeof v);     // 清零     lc[0] = 0;                  // 选0号为起始节点     v[0] = 1;    for (int i = 1; i < n; i++) {        lc[i] = d[0][i];    }    for (int i = 1; i < n; i++) {        int m = inf, tmp;        for (int j = 0; j < n; j++) {            if (!v[j] && m > lc[j]) {                m = lc[tmp = j];            }        }        ans += m;        lc[tmp] = 0;        v[tmp] = 1;        for (int j = 0; j < n; j++) {            lc[j] = min(lc[j], d[tmp][j]);        }    }    return ans;}

阅读原文

0 0