P2872

传送门

首先

题目概括:题目让着求使所有牧场都联通.需要修建多长的路.

显然这是一道最小生成树板子题(推荐初学者做).

那我就说一下kruskal吧.

Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表。

用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。

和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。------- 来自于百度百科

一、基本思路

kruskal利用了一种贪心的思想,先把每一条边按照边权排一下序,利用并查集维护每一个点.

跑kruskal的时候先判断两个点是不是在一个集合里边,如果在那就说明不用再去连边了.

然后合并的时候记录边权,在搞一个记录加的边数的计数器.

大家都知道一张图如果有\(n\)个节点,那么最少\(n-1\)条边就可以吧这张图搞联通了.

那么我们就可以等到计数器的计数记到\(n-1\) 的时候停止执行(已经得到正解).

然后因为这\(n-1\)条边把图连成一起,那么显然\(n - m\)条边就可以把图分成m个部分(很好想鸭).例题:P1195

二、代码

for (int i = 1; i <= cnt; i++) {
if (father(edge[i].x) != father(edge[i].y)) {//判断是不是在一个集合中
f++;
unionn(edge[i].x, edge[i].y);//合并
ans += edge[i].dis;//记录总权值
}
if (f == m) break;//如果做完了,那就停下啊.
}

此题代码及思路:

因为有一些边是一开始就有的,那么我们可以吧一开始就有的那些边都赋值成0,然后继续跑kruskal就好了.

因为给出的是坐标,那就先把坐标都存起来,然后把这些坐标依照欧几里得距离两两建边.

欧几里得距离公式:\(\sqrt{((x_{1}-x_{2})*(x_{1}-x_{2}) + (y_{1}-y_{2}) * (y_{1}-y_{2}))}\)

#include <bits/stdc++.h>

#define N 1000010
#define M 2010 using namespace std;
int fath[M], n, m; bool b[M];
double px[M], py[M];
struct node {//结构体存边.
int x, y;
double dis;
}edge[N << 2]; int read() {
int s = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
} int father(int x) {
if (x != fath[x]) fath[x] = father(fath[x]);//求是不是在一个集合里
return fath[x];
} void unionn(int x, int y) {
int fx = father(x), fy = father(y);//合并两个集合
fath[x] = fath[y];
} bool cmp(node p, node q) {
return p.dis < q.dis;//sort用品
} int main() {
n = read(), m = read();
int z = n + m;//原本就有的
for (int i = 1; i <= z; i++) fath[i] = i;
int cnt = 0;
for (int i = 1, x, y; i <= n; i++) {
x = read(), y = read();
px[i] = x, px[i] = y;//因为给出的是坐标,先把坐标存起来.
}
for (int i = 1; i <= n; i++) fath[i] = 1;
for (int i = n + 1, x, y; i <= n + m; i++) {
x = read(), y = read();
px[i] = x, py[i] = y;
}
for (int i = 1; i <= n + m; i++) {
for (int j = i + 1; j <= n + m; j++) {//开始存边
cnt++;
edge[cnt].x = i;
edge[cnt].y = j;
edge[cnt].dis = sqrt((px[i] - px[j]) * (px[i] - px[j]) + (py[i] - py[j]) * (py[i] - py[j]));
}
}
sort(edge + 1, edge + cnt + 1, cmp);//给边排一下序
int f = 0;
double ans = 0;
for (int i = 1; i <= cnt; i++) {//kruskal
if (father(edge[i].x) != father(edge[i].y)) {
f++;
unionn(edge[i].x, edge[i].y);
ans += edge[i].dis;
}
if (f == m) break;
}
printf("%.2lf", ans);
}

洛谷 P2872 【[USACO07DEC]道路建设Building Roads】的更多相关文章

  1. 洛谷——P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  2. 洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  3. 洛谷 P2872 [USACO07DEC]道路建设Building Roads

    题目描述 Farmer John had just acquired several new farms! He wants to connect the farms with roads so th ...

  4. bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads kruskal求最小生成树. #include<iostream> #include<cstdio> ...

  5. $P2872\ [USACO07DEC]道路建设Building\ Roads$

    \(problem\) 错的原因是\(RE\)(大雾 , 时刻谨记 \(N\) 个地方的话 保守开 \(\frac{N^2}{2}\) 大小. 因为是边. 边最多的情况即完全图 : $1+2+3+4. ...

  6. [USACO07DEC]道路建设Building Roads

    题目:洛谷P2872.POJ3625. 题目大意:给你n个点的坐标,有些点已经有边连通,现在要你连上剩下的所有点,求这些边的最小长度是多少(不包括原来的边). 解题思路:最小生成树,把所有边处理出来, ...

  7. 题解 P2872 【[USACO07DEC]道路建设Building Roads】

    这道题真的是令人窒息,Kruskal调了贼久一直RE,最后发现数组大小稍微少了那么一点点.(也就10倍吧..) 言归正传,根据本人的分析(以及算法标签的提示),这是一道求最小生成树的题目,当然要注意已 ...

  8. USACO 07DEC 道路建设(Building Roads)

    Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he ...

  9. 洛谷 P5019 铺设道路

    题目描述 春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度 ...

随机推荐

  1. 封装:WPF绘制曲线视图

    原文:封装:WPF绘制曲线视图 一.目的:绘制简单轻量级的曲线视图 二.实现: 1.动画加载曲线 2.点击图例显示隐藏对应曲线 3.绘制标准基准线 4.绘制蒙板显示标准区域 曲线图示例: 心电图示例: ...

  2. 无法打开内核设备:\\Global\\vmx86

    关于如题目的问题,网上有好几个解决办法,这里只介绍最方便的一个办法,利用脚本来解决 @Echo Off title Hankcs's program color 8F CD %~d0 CD %~dp0 ...

  3. Mysql之索引(六)

    1.思考 在图书馆是怎么找到一本书的? 一般的应用系统对比数据库的读写比例在10:1左右(即有10次查询有1次写操作),而且插入操作和更新操作很少出现性能问题. 遇到最多,最复杂的还是一些复杂的查询操 ...

  4. Java自学-异常处理 处理

    Java的异常处理办法 try catch throws 异常处理常见手段: try catch finally throws 步骤 1 : try catch 1.将可能抛出FileNotFound ...

  5. 使用MHA实现MySQL主从复制高可用

    一.MHA简介        MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司的youshimaton(现就职于Fac ...

  6. Java检查字符串是否包含中文字符

    转自:https://blog.csdn.net/zhanghan18333611647/article/details/80038629 强烈推荐一个大神的人工智能的教程:http://www.ca ...

  7. 上传文本到hdfs上的一些命令

    在hadoop下创建文件夹 bin/hdfs dfs -mkdir -p /usr/hadoop/spark/ touch wc.input  写一些文本进去. 上传到hdfs上  bin/hdfs ...

  8. 全网最全Selenium相关资源汇总

    官网: Selenium官网:https://docs.seleniumhq.org Selenium github: https://github.com/SeleniumHQ/selenium 文 ...

  9. Flask的上下文管理

    flask上下文管理 1.运用的知识点 val = threading.local() def task(arg): #threading.local() val.xxx=123 #内部,获取当前线程 ...

  10. Beta冲刺第5次

    二.Scrum部分 1. 各成员情况 翟仕佶 学号201731103226 今日进展 新增将图片转为粉笔画功能代码 存在问题 难者不会,会者不难,主要是参数设置问题 明日安排 视情况而定,可能还是写扩 ...