博客
关于我
cf 1095f kruskal模板题 kruskal适合稀疏图 prim适合稠密图
阅读量:293 次
发布时间:2019-03-03

本文共 2701 字,大约阅读时间需要 9 分钟。

为了解决这个问题,我们需要找到一种方法,使得在给定的点和额外边的条件下,连接所有点的总代价最小。我们可以使用Kruskal算法来解决这个问题,因为它适合处理稀疏图。

方法思路

  • 问题分析:我们需要连接所有的点,使得任意两点之间的代价最小。每个点有一个权值,原图中每个点对之间有一条边,边的权值是两个点的权值之和。我们还可以选择额外的边来替代这些边,从而降低总代价。

  • 关键思路:找到权值最小的点t,将其他所有点连接到t。这样,连接t到其他点的边的权值是最小的。然后,剩下的边选择权值最小的边来连接其他点。

  • 算法选择:使用Kruskal算法来找到最小生成树。Kruskal算法适合处理稀疏图,时间复杂度为O(m log m),适合处理大规模数据。

  • 实现步骤

    • 找到权值最小的点t。
    • 构造边集合,包括额外边和t与其他点之间的边。
    • 使用Kruskal算法在边集合中找到最小生成树的总权值。
  • 解决代码

    题意:

    n个点,每个点有一个权值node[i],在第i个点和第j个点之间连无向边的代价为node[i]+node[j],有m条额外边可选择,第u个点和第v个点连无向边的代价为w,额外边可以用可以不用。问连边使任意两点可连通的总代价是多少。

    数据范围:1 ≤ n ≤ 2e5 , 0 ≤ m ≤ 2e5。

    题解:

    1. 使用Kruskal算法求最小生成树。

    2. 找到权值最小的点t,将除t之外的点和t相连,原有的边与m条额外边共同组成可选的边集合E。

    3. n ≤ 2e5,由于边是无向的且包括原有的边和额外边,总边数cnt ≤ 8e5,远小于2e5 * 2e5,是稀疏图,使用Kruskal算法。

    4. Prim算法复杂度O(n²)不适合,Kruskal算法复杂度O(m log m)适合。

        #include 
    #define N 800005
    using namespace std;
    int n, m, cnt = 0;
    long long node[N];
    int pre[N];
    struct Edge {
    int u, v;
    long long weight;
    };
    int find(int x) {
    if (x == pre[x])
    return pre[x];
    pre[x] = find(pre[x]);
    return pre[x];
    }
    bool cmp(const Edge &a, const Edge &b) {
    return a.weight < b.weight;
    }
    void kruskal() {
    int i, j;
    int u, v;
    int ru, rv;
    long long sum = 0;
    sort(edges, edges + cnt, cmp);
    for (i = 0; i < cnt; ++i) {
    u = edges[i].u;
    v = edges[i].v;
    ru = find(u);
    rv = find(v);
    if (ru == rv)
    continue;
    pre[ru] = rv;
    sum += edges[i].weight;
    }
    cout << sum << endl;
    }
    int main() {
    int i, j;
    Edge a;
    scanf("%d%d", &n, &m);
    for (i = 1; i <= n; ++i) {
    scanf("%lld", &node[i]);
    if (node[i] < min_node) {
    min_node = node[i];
    t = i;
    }
    pre[i] = i;
    }
    for (i = 1; i <= n; ++i) {
    if (i == t)
    continue;
    a.u = t;
    a.v = i;
    a.weight = node[t] + node[i];
    edges[cnt++] = a;
    a.u = i;
    a.v = t;
    edges[cnt++] = a;
    }
    for (i = 1; i <= m; ++i) {
    scanf("%d%d%lld", &u, &v, &w);
    a.u = u;
    a.v = v;
    a.weight = w;
    edges[cnt++] = a;
    a.u = v;
    a.v = u;
    edges[cnt++] = a;
    }
    kruskal();
    }

    代码解释

  • 读取输入:读取点数n和额外边数m,然后读取每个点的权值,找到权值最小的点t。
  • 构造边集合:构造边集合,包括t与其他点之间的边,以及额外的边。
  • Kruskal算法:对边集合进行排序,使用并查集算法找到最小生成树的总权值。
  • 这个方法确保了在给定的约束条件下,连接所有点的总代价最小。

    转载地址:http://bpml.baihongyu.com/

    你可能感兴趣的文章
    NN&DL4.3 Getting your matrix dimensions right
    查看>>
    NN&DL4.7 Parameters vs Hyperparameters
    查看>>
    NN&DL4.8 What does this have to do with the brain?
    查看>>
    nnU-Net 终极指南
    查看>>
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    查看>>
    NO 157 去掉禅道访问地址中的zentao
    查看>>
    no available service ‘default‘ found, please make sure registry config corre seata
    查看>>
    No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    查看>>
    no connection could be made because the target machine actively refused it.问题解决
    查看>>
    No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
    查看>>
    No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
    查看>>
    No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
    查看>>
    No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
    查看>>
    No mapping found for HTTP request with URI [/logout.do] in DispatcherServlet with name 'springmvc'
    查看>>
    No module named 'crispy_forms'等使用pycharm开发
    查看>>
    No module named cv2
    查看>>
    No module named tensorboard.main在安装tensorboardX的时候遇到的问题
    查看>>
    No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
    查看>>
    No new migrations found. Your system is up-to-date.
    查看>>
    No qualifying bean of type XXX found for dependency XXX.
    查看>>