最小生成树

记录
18:22 2024-2-1

1.最小生成树

1.Prim

类似dijkstra,优化可以用最小堆来维护权值最小边

点击查看代码
const int INF = 0x3f3f3f3f;

int cost[MAX_V][MAX_V]; // cost[u][v]边e(u,v)的权重 不存在设为INF
int mincost[MAX_V];
bool used[MAX_V];
int V;

int prim() {
    for(int i = 0; i < V; i++) {
        mincost[i] = INF;
        used[i] = false;
    }

    mincost[0] = 0;
    int res = 0;

    while (true) {
        int v = -1;
        for(int u = 0; u < V; u++) {
            if(!used[u] && (v == -1 || mincost[u] < mincost[v])) v = u;
        }

        if(v == -1) break;
        used[v] = true;
        res += mincost[v];

        for(int u = 0; u < V; u++) {
            mincost[u] = min(mincost[u], mincost[v] + cost[v][u]);
        }
    }
    return res;
}

2.Kruskal

点击查看代码
void init(int n) {
    for(int i = 0; i < n; i++) {
        par[i] = i;
        ran[i] = 0;
    }
}

int find(int x) {
    if(par[x] == x) {
        return x;
    } else {
        return par[x] = find(par[x]);
    }
}

void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if(x == y) return;

    if(ran[x] < ran[y]) {
        par[x] = y;
    } else {
        par[y] = x;
        if(ran[x] == ran[y]) ran[x]++;
    }
}

bool same(int x, int y) {
    return find(x) == find(y);
}

struct edge {int u, v, cost;};

bool comp(const edge &e1, const edge &e2) {
    return e1.cost < e2.cost;
}

edge es[MAX_E];
int V, E;

int kruskal() {
    sort(es, es + E, comp); // 按照edge.cost的顺序 从小到大
    init(V);        //初始化 并查集
    int res = 0;
    for(int i = 0; i < E; i++) {
        edge e = es[i];
        if(!same(e.u, e.v)) {
            unite(e.u, e.v);
            res += e.cost;
        }
    }
    return res;
}
posted @ 2024-02-05 18:14  57one  阅读(2)  评论(0编辑  收藏  举报