博客
关于我
HDU 1102 Constructing Roads
阅读量:131 次
发布时间:2019-02-27

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

构造最小生成树以连接所有村庄。已知村庄之间的距离以及已有的连接边,使用Kruskal算法找到最小生成树的总权值。

题目大意是:有N个村庄,每个村庄间的距离已知。已知某些村庄之间有直接连接的道路,要求建造最少长度的道路,使得所有村庄互相连接。解决方法是使用Kruskal算法,构造最小生成树。

首先,读取输入数据,包括村庄间距离矩阵和已有的连接边。将所有可用的边进行排序,权重从小到大排列。使用并查集数据结构来跟踪各村庄的连通性。

遍历排序后的边,对于每条边,检查其连接的两个村庄是否在同一连通集合中。如果不在同一集合中,将这条边加入生成树,并将其权重累加到总长度中,同时合并两个村庄所在的集合。继续处理下一条边,直到形成包含所有村庄的连通图。

最终,输出生成树的总权重,即为所需最小的新建道路总长度。

解题步骤:

  • 读取村庄数量N和距离矩阵。
  • 读取已有的Q条连接边,记录其权重为0。
  • 收集所有村庄间的可用边,计算权重。
  • 按权重排序所有边。
  • 初始化并查集。
  • 遍历边,逐步合并连通的村庄,累加权重。
  • 当所有村庄连通时,输出总权重。
  • 代码实现:

    #include 
    #include
    #include
    using namespace std;
    #define MaxSize 101
    #define INF 0x7fffffff
    typedef struct Edge {
    int u;
    int v;
    int w;
    } Edge;
    int cmp(const void *a, const void *b) {
    const Edge *c = (Edge *)a;
    const Edge *d = (Edge *)b;
    if (c->w != d->w) return c->w - d->w;
    else return d->u - c->u;
    }
    void kruskal(int dist[][MaxSize], int n, int &sum) {
    int edges = n * n;
    Edge E[edges];
    int k = 0;
    for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
    if (dist[i][j] != INF) {
    E[k].u = i;
    E[k].v = j;
    E[k].w = dist[i][j];
    k++;
    }
    }
    }
    qsort(E, k, sizeof(Edge), cmp);
    int vset[n];
    for (int i = 0; i < n; ++i) {
    vset[i] = i;
    }
    int j = 0;
    int components = n;
    sum = 0;
    for (int k = 0; k < k; ++k) {
    if (components == n) break;
    int u = E[k].u;
    int v = E[k].v;
    int root_u = vset[u];
    int root_v = vset[v];
    if (root_u != root_v) {
    sum += E[k].w;
    if (root_u > root_v) {
    vset[root_u] = root_v;
    } else {
    vset[root_v] = root_u;
    }
    components--;
    }
    }
    }
    int main() {
    int n, q, sum = 0;
    while (cin >> n) {
    int dist[n][MaxSize];
    for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
    cin >> dist[i][j];
    }
    }
    cin >> q;
    for (int i = 0; i < q; ++i) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    if (dist[a][b] == 0) {
    dist[a][b] = 0;
    dist[b][a] = 0;
    } else {
    dist[a][b] = 0;
    dist[b][a] = 0;
    }
    }
    kruskal(dist, n, sum);
    cout << sum << endl;
    }
    return 0;
    }

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

    你可能感兴趣的文章
    node.js的express框架用法(一)
    查看>>
    Node.js的交互式解释器(REPL)
    查看>>
    Node.js的循环与异步问题
    查看>>
    Node.js高级编程:用Javascript构建可伸缩应用(1)1.1 介绍和安装-安装Node
    查看>>
    nodejs + socket.io 同时使用http 和 https
    查看>>
    NodeJS @kubernetes/client-node连接到kubernetes集群的方法
    查看>>
    NodeJS API简介
    查看>>
    Nodejs express 获取url参数,post参数的三种方式
    查看>>
    nodejs http小爬虫
    查看>>
    nodejs libararies
    查看>>
    nodejs npm常用命令
    查看>>
    nodejs npm常用命令
    查看>>
    Nodejs process.nextTick() 使用详解
    查看>>
    NodeJS yarn 或 npm如何切换淘宝或国外镜像源
    查看>>
    nodejs 中间件理解
    查看>>
    nodejs 创建HTTP服务器详解
    查看>>
    nodejs 发起 GET 请求示例和 POST 请求示例
    查看>>
    NodeJS 导入导出模块的方法( 代码演示 )
    查看>>
    nodejs 开发websocket 笔记
    查看>>
    nodejs 的 Buffer 详解
    查看>>