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

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

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

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

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

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

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

解题步骤:

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

    #include 
    #include
    #include
    using namespace std;#define MaxSize 101#define INF 0x7ffffffftypedef 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/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | OpenCV如何读取仪表中的指针刻度
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(一) :直接拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(三):基于特征匹配拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(二) :基于模板匹配拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(四):基于Stitcher类拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测(建议收藏!)
    查看>>
    OpenCV与AI深度学习 | PaddleOCR 2.9 发布, 正式开源文本图像智能分析利器
    查看>>
    OpenCV与AI深度学习 | SAM2(Segment Anything Model 2)新一代分割一切大模型介绍与使用(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | T-Rex Label !超震撼 AI 自动标注工具,开箱即用、检测一切
    查看>>
    OpenCV与AI深度学习 | YOLO11介绍及五大任务推理演示(目标检测,图像分割,图像分类,姿态检测,带方向目标检测)
    查看>>
    OpenCV与AI深度学习 | YOLOv10在PyTorch和OpenVINO中推理对比
    查看>>
    OpenCV与AI深度学习 | YOLOv11来了:将重新定义AI的可能性
    查看>>
    OpenCV与AI深度学习 | YOLOv8自定义数据集训练实现火焰和烟雾检测(代码+数据集!)
    查看>>
    OpenCV与AI深度学习 | YOLOv8重磅升级,新增旋转目标检测,又该学习了!
    查看>>
    OpenCV与AI深度学习 | 一文带你读懂YOLOv1~YOLOv11(建议收藏!)
    查看>>
    OpenCV与AI深度学习 | 五分钟快速搭建一个实时人脸口罩检测系统(OpenCV+PaddleHub 含源码)
    查看>>
    OpenCV与AI深度学习 | 什么是 COCO 数据集?
    查看>>
    OpenCV与AI深度学习 | 低对比度缺陷检测应用实例--LCD屏幕脏污检测
    查看>>
    OpenCV与AI深度学习 | 使用 MoveNet Lightning 和 OpenCV 实现实时姿势检测
    查看>>
    OpenCV与AI深度学习 | 使用 OpenCV 创建自定义图像滤镜
    查看>>