欧拉回路 - 铲雪车 - AcWing 1123
随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。
整个城市所有的道路都是双向车道,道路的两个方向均需要铲雪。因为城市预算的削减,整个城市只有 1 辆铲雪车。
铲雪车只能把它开过的地方(车道)的雪铲干净,无论哪儿有雪,铲雪车都得从停放的地方出发,游历整个城市的街道。
现在的问题是:最少要花多少时间去铲掉所有道路上的雪呢?
输入格式
输入数据的第 1 行表示铲雪车的停放坐标 (x,y),x,y 为整数,单位为米。
下面最多有4000行,每行给出了一条街道的起点坐标和终点坐标,坐标均为整数,所有街道都是笔直的,且都是双向车道。
铲雪车可以在任意交叉口、或任何街道的末尾任意转向,包括转 U 型弯。
铲雪车铲雪时前进速度为 20 千米/时,不铲雪时前进速度为 50 千米/时。
保证: 铲雪车从起点一定可以到达任何街道。
输出格式
输出铲掉所有街道上的雪并且返回出发点的最短时间,精确到分钟,四舍五入到整数。
输出格式为”hours:minutes”,minutes不足两位数时需要补前导零。
具体格式参照样例。
数据范围
− 1 0 6 ≤ x , y ≤ 1 0 6 −10^6≤x,y≤10^6 −106≤x,y≤106
所有位置坐标绝对值不超过 106。
输入样例:
0 0
0 0 10000 10000
5000 -10000 5000 10000
5000 10000 10000 10000
输出样例:
3:55
样例解释
输出结果表示共需3小时55分钟。
分析:
由 题 意 , 给 定 一 个 图 , 由题意,给定一个图, 由题意,给定一个图,
要 经 过 图 中 每 条 边 至 少 两 次 , 求 遍 历 这 个 图 的 最 短 时 间 是 多 少 , 要经过图中每条边至少两次,求遍历这个图的最短时间是多少, 要经过图中每条边至少两次,求遍历这个图的最短时间是多少,
由 于 车 速 固 定 , 等 价 于 计 算 出 遍 历 这 个 图 的 路 程 和 的 最 小 值 是 多 少 。 由于车速固定,等价于计算出遍历这个图的路程和的最小值是多少。 由于车速固定,等价于计算出遍历这个图的路程和的最小值是多少。
尽 管 不 铲 雪 的 速 度 是 50 k m / h , 但 是 若 走 过 多 余 的 路 程 , 仍 然 不 是 最 短 路 程 。 尽管不铲雪的速度是50km/h,但是若走过多余的路程,仍然不是最短路程。 尽管不铲雪的速度是50km/h,但是若走过多余的路程,仍然不是最短路程。
因 此 , 我 们 要 确 保 经 过 边 的 数 量 尽 量 少 。 因此,我们要确保经过边的数量尽量少。 因此,我们要确保经过边的数量尽量少。
但是本题应当看作是有向图,而非无向图。
原因:
本 题 要 求 每 条 边 一 来 一 回 经 过 两 次 , 本题要求每条边一来一回经过两次, 本题要求每条边一来一回经过两次,
若 看 作 有 向 图 , 由 于 每 条 边 都 会 对 边 的 两 个 端 点 贡 献 1 个 出 度 和 1 个 入 度 , 若看作有向图,由于每条边都会对边的两个端点贡献1个出度和1个入度, 若看作有向图,由于每条边都会对边的两个端点贡献1个出度和1个入度,
这 就 保 证 了 每 个 点 的 出 度 和 入 度 相 等 , 从 而 确 定 图 中 存 在 欧 拉 回 路 。 这就保证了每个点的出度和入度相等,从而确定图中存在欧拉回路。 这就保证了每个点的出度和入度相等,从而确定图中存在欧拉回路。
若 看 作 是 无 向 图 , 相 当 于 同 一 条 边 经 过 两 次 。 则 不 能 确 定 是 否 存 在 欧 拉 回 路 。 若看作是无向图,相当于同一条边经过两次。则不能确定是否存在欧拉回路。 若看作是无向图,相当于同一条边经过两次。则不能确定是否存在欧拉回路。
故 本 题 的 最 优 解 , 应 当 是 欧 拉 回 路 正 向 和 反 向 各 跑 一 遍 。 故本题的最优解,应当是欧拉回路正向和反向各跑一遍。 故本题的最优解,应当是欧拉回路正向和反向各跑一遍。
我 们 仅 需 将 所 有 边 权 累 加 起 来 即 可 得 出 最 短 路 程 。 我们仅需将所有边权累加起来即可得出最短路程。 我们仅需将所有边权累加起来即可得出最短路程。
注意:
计 算 距 离 的 时 候 , 考 虑 到 一 些 精 度 问 题 , 将 点 坐 标 类 型 设 置 成 d o u b l e 。 计算距离的时候,考虑到一些精度问题,将点坐标类型设置成double。 计算距离的时候,考虑到一些精度问题,将点坐标类型设置成double。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
double get_dis(double a1,double b1,double a2,double b2)
{
double dx=a1-a2, dy=b1-b2;
return sqrt(dx*dx+dy*dy);
}
int main()
{
double a1,b1,a2,b2;
cin>>a1>>b1;
double sum=0;
while(cin>>a1>>b1>>a2>>b2) sum+=get_dis(a1,b1,a2,b2);
sum=sum/1000*2;
int minute=round(sum/20*60);
int hour=minute/60;
minute%=60;
printf("%d:%02d\n",hour,minute);
return 0;
}