铲雪车
题目描述
前置知识
无向图:
- 存在欧拉路径的充要条件 : 度数为奇数的点只能有0或2个
- 存在欧拉回路的充要条件 : 度数为奇数的点只能有0个,即不存在度数为奇数的点,全都是度为偶数的点
有向图:
- 存在欧拉路径的充要条件:
- 要么所有点的出度均等于入度,即入度 = = =出度
- 要么除了两个点之外,其他所有点的入度 = = =出度,剩下的两个点,其中一个点满足出度=入度+1(起点),另一个点满足入度=出度+1(终点)
- 存在欧拉回路的充要条件:所有点的出度均等于入度,即入度 = = =出度
核心思路
题目中说到”道路都是双向车道,道路的两个方向均需要铲雪“,则对每个点来说,都有入度=出度。根据有向图中存在欧拉回路的充要条件可知,此时必然存在欧拉回路。那么题目中想要求的最短时间就是 刚好一笔画完所有双向边。而欧拉回路刚好就是从一个点开始只遍历所有边一次,然后又回到这个点。 因此,我们只需要计算这些边的总距离就好了,设为 L L L,由于是双向,因此要乘以,即 2 × L 2\times L 2×L
如下图:
所以这题看起来很复杂,但是需要认真读清题意,才会发现如此简单,都不需要建图,而是统计边的长度就好了,那么最短时间就是 2 × L 2\times L 2×L除以速度即可。
注意题目中输入的坐标的单位是米,但是给出的速度是 k m / h km/h km/h,因此需要把米转化为千米。需要四舍五入到整数,因此还需要用到round函数。
代码
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
double sx,sy;
double x1,y1,x2,y2;
double sum=0;
cin >>sx>>sy; //读入铲雪车的停放坐标
//读入一条街道的起点坐标和终点坐标
while(cin >>x1>>y1>>x2>>y2)
{
double dx=x1-x2;
double dy=y1-y2;
sum+=sqrt(dx*dx+dy*dy)*2; //总距离
}
int minutes=round(sum/1000/20*60); //四舍五入到整数
int hours=minutes/60;
minutes%=60;
printf("%d:%02d\n",hours,minutes);
return 0;
}