zoukankan      html  css  js  c++  java
  • 最小生成树


    最小生成树:对于带权图,权值和最小的生成树
    最小瓶颈生成树:对于带权图,最大权值最小的生成树
    最小生成树一定是最小瓶颈生成树

    1:prim:

    bool vis[MAXN];
    int minc[MAXN];
    priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
    int prim() {
    int ans = 0;
    q.push(make_pair(0, 1));
    while (!q.empty()) {
    int c = q.top().first, now = ed[q.top().second].to;
    if (!vis[now]) {
    vis[now] = true;
    ans += c;
    insert(ed[i].from, ed[i].to, ed[i].cost);
    insert(ed[i].to, ed[i].from, ed[i].cost);
    for (int i = he[now]; i; i = ne[i]) {
    Edge &e = ed[i];
    if (minc[e.to] > e.cost && !vis[e.to]) {
    minc[e.to] = e.cost;
    q.push(make_pair(e.cost, i));
    }
    }
    }
    }
    return ans;
    }


    随意选取一个点作为已访问集合的第一个点,并将所有相连的边加入堆中
    -
    从堆中找到最小的连接集合内和集合外点的边,将边加入最小生成树中
    -
    将集合外点标记为已访问,并将相连边加入堆

    重复以上过程直到所有点都在访问集合中

    2:kruskal

    struct UnionSet {
    int f[MAXN];
    UnionSet(int n) {
    for (int i = 1; i <= n; i++) {
    f[i] = i;
    }
    }
    UnionSet(){}

    void uni(int x, int y) {
    f[find(x)] = find(y);
    }

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

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

    } us;

    void kruskal() {
    sort(edges, edges+m);
    us = UnionSet(n);
    for (int i = 0; i < m && etop < n * 2 - 1; i++) {
    Edge &e = edges[i];
    if (!us.query(e.from, e.to)) {
    insert(e.from, e.to, e.dist);
    insert(e.to, e.from, e.dist);
    us.uni(e.from, e.to);
    }
    }
    }


    将边按照权值排序

    依次枚举每一条边,若连接的两点不连通则加入最小生成树中

    使用并查集维护连通性

  • 相关阅读:
    C# WebSocket 实现客户端和服务端的通信(二)
    C# WebSocket 实现客户端和服务端的通信(一)
    regsvr32 将dll写入注册表
    Dictionary 添加重复的键值对
    C# Math.Round()的银行家算法
    DataGridView 合并数据相同的行
    获取系统当前日期,分布获取年月日和时分秒
    [Err] ORA-00923: 未找到要求的 FROM 关键字
    正则表达式常用的字符类
    Spring注解作用
  • 原文地址:https://www.cnblogs.com/zyfltyyz/p/11719158.html
Copyright © 2011-2022 走看看