国庆六日游——第一天第一题
国庆六日游——第一天第一题
普及组请出门右转
萌新出门左转
正题:
一场天灾过后,B市的所有主干道路都被切断了。
灾后重建的一项重要任务是恢复通信。B市共有n个关键的据点,而我们现在有一条关键的消息,需要所有的据点都要收到。
消息的传递有两种方式:
空降:可以直接将消息传给某个据点,每次需要的代价为v。
通信员:可以将消息从一个据点传到另一个据点,需要的代价为两个据点在地图上的欧氏距离的平方。
注意,通信员只能从已有消息的据点传递消息到另一个据点。所以,至少第一个收到消息的据点一定是通过空降的。
在保证所有的据点都收到消息的前提下,最小的总代价是多少?
输入的第一行包含空格隔开的两个数n,v。
接下来n行,每行有两个空格隔开的数x,y,表示每个据点在地图上的坐标。
输出一行,仅包含一个整数,表示最小的总代价。
保证n <= 5000, v <= 100000, x, y <= 30000;
时限 1000ms 空间限制 128MB
样例:
6 1000
0 0
0 10
20 20
30 30
80 100
100 100
输出:
3200
思路
假如没有“空降”这个条件,这题显然就是坐标转换最小生成树。
“最小的总代价”对应“最小”, 所有据点收到消息 对应 生成树
可是题目连“边”和“边权”都没有出现, 哪儿来的图?
自己YY据点和据点两两连线,连成一个完全图,边权为两点之间的欧氏距离。
辣么怎么处理“空降”的条件呢?
处理不了,告辞
这时候我们就需要拿出我们万能的笔和纸,使出必杀技——画一画!
(手动求生欲
以样例为例,画出来应该是这样:
GeoGebra生成图片
经过看题解仔细观察,细心的人可能发现,空降的次数等于图中联通块的个数。
看到这里,大概会有人和我一样开始考虑求联通块的方法。
但这种思路有一个本质的问题——我们首先要得到这个图,然后才能求联通块。
一种解决办法是把所有边权大于v的边全部换成v,然后再用Kruskal求解
撒花完结!
看看数据范围
n <= 5000
笑容逐渐消失
Kruskal : 我太难了
Prim : 终于到我出场了
把边权换成v的本质是什么?
复读机
观察下面的图:
于是,我们可以加入一个虚拟节点,这个节点到每一个点的距离都是v
但是,先别急着加边!如果我们从虚拟节点开始“搜索”,会发现它每一条出边的权值都是v(废话),我们可以省去加虚拟边的过程,直接把每个点的dist初始化为v。
(以上看不懂可以先复习一下Prim算法)
上代码:
#include<bits/stdc++.h>
#define int long long
//以下是读入输出优化,看不懂可以直接用cin/scanf, cout/printf代替
#define MAX_INPUT maxi
using namespace std;
namespace IO{const int MAX_INPUT = 1000000;#define getc() (p1 == p2 && (p2 = (p1 = buf) + inbuf -> sgetn(buf, MAX_INPUT), p1 == p2) ? EOF : *p1++)char buf[MAX_INPUT], *p1, *p2;template <typename T> inline bool redi(T &x) {static std::streambuf *inbuf = cin.rdbuf();x = 0;register int f = 0, flag = false;register char ch = getc();while (!isdigit(ch)) {if (ch == '-') f = 1;ch = getc();}if (isdigit(ch)) x = x * 10 + ch - '0', ch = getc(),flag = true;while (isdigit(ch)) {x = x * 10 + ch - 48;ch = getc();}x = f ? -x : x ;return flag;} //以上是读入#undef getctemplate <typename T> inline void put(const char ch,T x){static std::streambuf *outbuf = cout.rdbuf();static char stack[21];static int top = 0;if (x < 0) {outbuf -> sputc('-');x=-x;}if (!x) {outbuf -> sputc('0');outbuf -> sputc(ch);return;}while (x) {stack[++top] = x % 10 + '0';x /= 10;}while (top) {outbuf -> sputc(stack[top]);--top;}outbuf -> sputc(ch);} //以上是输出
}using namespace IO;
//以上是IO优化
int n;
const int man = 5010;
pair<int, int> node[man]; //据点坐标
int dist[man], vis[man];
#define x first //避免手残
#define y second
//如果不喜欢用pair,可以自己定义一个结构体
signed main() {//freopen("inform.in", "r", stdin);//freopen("inform.out", "w", stdout); //不解释memset(vis, false, sizeof(vis)); //可有可无,应该默认falseredi(n); int v; redi(v); int tot; //tot即为当前总代价for(int i = 1; i <= n; ++i) {redi(node[i].x);redi(node[i].y);dist[i] = v; //刚才说的虚拟节点} sort(node + 1, node + n + 1); //排序for(int i = 1; i <= n; ++i) {int temp = 0x3f3f3f3f, ansn; //初始化for(int j = 1; j <= n; ++j) {if(dist[j] < temp && !vis[j]) {temp = dist[j]; ansn = j; //记录最小代价的出路?}}tot += temp; //更新总代价vis[ansn] = true; //避免重复访问for(int j = 1; j <= n; ++j) {dist[j] = min(dist[j], (node[ansn].x - node[j].x) * (node[ansn].x - node[j].x) + (node[ansn].y - node[j].y) * (node[ansn].y - node[j].y));//计算并更新,如果觉得难看可以写一个calc函数}} put('\n', tot); //输出
}
(真正的)撒花完结!
国庆六日游——第一天第一题相关推荐
- 国庆六日游——第三天第一题
国庆六日游--第三天第一题 别问我为什么不讲第二天 正题: 给定一个长度为2N的字符串S,S表示为2N个格子的染色情况.Si = B 时表示第i个格子为黑色,否则若Si = W表示第i个格子为白色. ...
- 第一章第二题(显示五条消息)(Display five messages)
第一章第二题(显示五条消息)(Display five messages) 1.2(显示五条消息)编写程序,显示 Welcome to Java 五次. 1.2 (Display five messa ...
- Dream_Chaser队训练赛第一场 K题
Dream_Chaser队训练赛第一场 K题 题目来自2012成都区域赛 K - Yet Another Multiple Problem Time Limit:20000MS Memory ...
- Dream_Chaser队训练赛第一场 I题
Dream_Chaser队训练赛第一场 I题 题目来自2012成都区域赛 I - Count Time Limit:1000MS Memory Limit:32768KB 64bit ...
- 2019年杭电多校第一场 1001题blank(DP)HDU6578
2019年杭电多校第一场 1001题blank(DP)HDU6578 解决思路,开一个DP数组来存储0 1 2 3四个字符最后出现的位置,并且在DP中已经==排好序==. DP开四维,DP[i][j] ...
- 计算机网络第一章考研题
计算机网络第一章考研题 文章目录 计算机网络第一章考研题 一.单项选择题 1.[2010统考真题]下列选项中,不属于网络体系结构所描述的内容是( ) 2.[2009统考真题]在OSI参考模型中, 自下 ...
- 中国石油大学《大学英语(三)统考》第一套模拟题
第一套模拟题 单选题 (共25道题) 收起 1.(4.0分) 1.- What do you do? _________ A.What do you do? B..Fine, thank you. C ...
- 2021年CSP-J入门级初赛(第一轮)真题讲解
2017年NOIP普及组初赛真题讲解 2017年NOIP普及组初赛真题讲解_哔哩哔哩_bilibili 2018年NOIP普及组初赛真题讲解 2018年NOIP普及组初赛真题讲解_哔哩哔哩_bilib ...
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
最新文章
- 基于visual Studio2013解决面试题之0901奇偶站队
- eclipse怎样生成javadoc
- 第十三届计算机语言学大会,第十三届全国语音学学术会议(PCC 2018) 会议通知第3号...
- Scala数组和Java集合互转代码演示
- 000 快速排序算法
- TensorFlow4-常量和变量及TensorBoard使用
- java get cookies_Java Cookie.getDomain方法代码示例
- elementUI使用
- iOS开发常用快捷键
- https验证失败+Android,okhttpSSL证书验证失败有关问题
- 电脑如何设置定时任务、定时执行 —— 不用Windows任务计划程序,也能轻松设定计划任务、定时任务 —— 定时执行专家
- 函数/极限/导数的概念辨析
- 团队项目开发——细思恐极
- 4.驱动框架入门之LED
- 昆仑通态屏幕制作(连载3)---基础篇(按钮串口发送)
- IE8运行脚本提示停止
- formvalidator4.1.3下载,formvalidator4.1.3下载地址,formvalidator4.1.3最新下载地址
- android启动速度测试,如何测试Android应用的启动速度?
- 数据库的三大范式详解
- 通过css设置鼠标的形状