题目描述

又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个 矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线, 所有航线单位里程的价格均为t。

图例(从上而下)

机场 高速铁路

飞机航线

  注意:图中并没有

标出所有的铁路与航线。

那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。

找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。

输入输出格式

输入格式:

第一行为一个正整数n(0<=n<=10),表示有n组测试数据。

每组的第一行有四个正整数s,t,A,B。

S(0<S<=100)表示城市的个数,t表示飞机单位里程的价格,A,B分别为城市A,B的序号,(1<=A,B<=S)。

接下来有S行,其中第I行均有7个正整数xi1,yi1,xi2,yi2,xi3,yi3,Ti,这当中的(xi1,yi1),(xi2,yi2),(xi3,yi3)分别是第I个城市中任意三个机场的坐标,T I为第I个城市高速铁路单位里程的价格。

输出格式:

共有n行,每行一个数据对应测试数据。 保留一位小数

输入输出样例

输入样例#1:

1
3 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3
输出样例#1:

47.5

最短路。

对于每个城市,根据已知的三个点坐标算出第四个点坐标,然后在同一城市的点之间两两连边(高铁),在不同城市的点之间两两连边(飞机),跑最短路即可。如何算第四个点的坐标?

首先由于四个点构成矩形,已知的三个点必构成直角三角形。通过比较三条边的长度可以找到直角顶点。具体看代码。

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
double dist(int x1,int y1,int x2,int y2){
return sqrt( (double)(x1-x2)*(x1-x2)+(double)(y1-y2)*(y1-y2) );
}
struct node{//点集
int x,y;
}a[mxn],p[];
int ncnt=;
int pdd(){//找直角边顶点
double d12=dist(p[].x,p[].y,p[].x,p[].y);
double d23=dist(p[].x,p[].y,p[].x,p[].y);
double d13=dist(p[].x,p[].y,p[].x,p[].y);
if(d12>d23 && d12>d13)return ;
if(d23>d12 && d23>d13)return ;
if(d13>d23 && d13>d12)return ;
}
void pos4(int tp){//算第四个点坐标
switch(tp){//根据直角顶点讨论。其实如果先把直角顶点swap到p[1]位置,代码可以更精简
case :{
p[].x=p[].x+p[].x-p[].x;
p[].y=p[].y+p[].y-p[].y;
break;
}
case :{
p[].x=p[].x+p[].x-p[].x;
p[].y=p[].y+p[].y-p[].y;
break;
}
case :{
p[].x=p[].x+p[].x-p[].x;
p[].y=p[].y+p[].y-p[].y;
break;
}
}
return;
}
struct edge{
int v,nxt;
double dis;
}e[mxn];
int hd[mxn],mct=;
void add_edge(int u,int v,double dis){
e[++mct].v=v;e[mct].dis=dis;e[mct].nxt=hd[u];hd[u]=mct;
return;
} int N;
int n,w,A,B; queue<int>q;
double dis[mxn];
bool inq[mxn];
void SPFA(int s){//最短路
for(int i=;i<=ncnt;i++)dis[i]=;
dis[s]=;inq[s]=;
q.push(s);
int i,j;
while(!q.empty()){
int u=q.front();q.pop();inq[u]=;
for(i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].dis){
dis[v]=dis[u]+e[i].dis;
if(!inq[v]){
inq[v]=;
q.push(v);
}
}
}
}
return;
}
int main(){
int i,j;
N=read();
while(N--){
memset(a,,sizeof a);
memset(e,,sizeof e);
memset(hd,,sizeof hd);
mct=ncnt=;
//
n=read();
w=read();A=read();B=read();
int X1,X2,X3,Y1,Y2,Y3,tt;
for(i=;i<=n;++i){
p[].x=read();p[].y=read();
p[].x=read();p[].y=read();
p[].x=read();p[].y=read();
tt=read();
pos4(pdd());
for(j=;j<=;j++)
for(int k=;k<=;k++){
if(k!=j)add_edge(ncnt+j,ncnt+k,dist(p[j].x,p[j].y,p[k].x,p[k].y)*tt);
}
for(j=;j<=;j++){
for(int k=;k<=ncnt;k++){
double dd=dist(p[j].x,p[j].y,a[k].x,a[k].y)*w;
add_edge(ncnt+j,k,dd);
add_edge(k,ncnt+j,dd);
}
}
for(j=;j<=;j++){a[++ncnt]=p[j];}
}
double ans=;
int st=(A-)*;
for(i=;i<=;i++){
SPFA(st+i);
int ed=(B-)*;
for(j=;j<=;j++){
// printf("%d to %d dis:%.1f\n",st+i,ed+j,dis[ed+j]);
ans=min(ans,dis[ed+j]);
}
}
printf("%.1f\n",ans);
}
return ;
}

[NOIP2001] 提高组 洛谷P1027 Car的旅行路线的更多相关文章

  1. 洛谷P1027 Car的旅行路线

    洛谷P1027 Car的旅行路线 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速 ...

  2. 洛谷 P1027 Car的旅行路线

    P1027 Car的旅行路线 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路 ...

  3. 洛谷 P1027 Car的旅行路线 最短路+Dijkstra算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1027 Car的旅行路线 题目描述 又到暑假了,住在 ...

  4. [NOIP2001] 提高组 洛谷P1026 统计单词个数

    题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保 证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的 ...

  5. [NOIP2001] 提高组 洛谷P1025 数的划分

    题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输 ...

  6. [NOIP2001] 提高组 洛谷P1024 一元三次方程求解

    题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差 ...

  7. 洛谷——P1027 Car的旅行路线

    https://www.luogu.org/problem/show?pid=1027#sub 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于 ...

  8. [NOIP2015] 提高组 洛谷P2615 神奇的幻方

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  9. [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

随机推荐

  1. redis源码分析之事务Transaction(下)

    接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...

  2. springboot的多个配置文件的关系

    一般我们在使用springboot时会用到多个环境下的配置文件,例如 application-dev.yml:开发环境 application-uat.yml:用户验收测试环境 application ...

  3. Windows程序设计2(消息机制、菜单)

    一 .小记; PostQuitMessage(0); 产生WM_QUIT消息给进程队列,且立即返回,同时使得消息循环退出,使得进程终止.(其实它通过PostMessage(hWnd,WM_QUIT,0 ...

  4. python基础一 day6 文件操作

    读写只会进行两步, r+模式下写读 seek是按字节去找的 for line in f: for循环是一行一行的读取出来 strip默认去空格和换行符 空格.制表符.换行符.回车.换页垂直制表符和换行 ...

  5. Java集合(四)--基于JDK1.8的ArrayList源码解读

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...

  6. Perl中 qw 是 “quoted Word” 或是 “quoted by whitespace”的简写

    Perl中 qw 是 “quoted Word” 或是 “quoted by whitespace”的简写 eg: @strict_pragma = qw ( a b c);

  7. Mac 安装Fiddler 抓包工具

    官方安装文档https://www.telerik.com/download/fiddler/fiddler-osx-beta 如果输入mono Fiddler.exe报下面这个错误 WARNING: ...

  8. g++使用总结

    学习C和C++的同学应该都知道,gcc是一款跨平台的C/C++编译器,可以在Linux/Windows平台下使用,具有十分强大的功能,结构也十分灵活,并且可以通过不同的前端模块来支持各种语言,如Jav ...

  9. 秋招复习-C++(三)

    • 数据库 1.数据库的索引有哪些? (1)B树索引:利用B树作为底层数据结构的索引,在B树索引中保存索引列的值和数据表的对应行的ID,每一个叶子结点都存放着一个索引列的值和数据表对应行的ID,通过这 ...

  10. 杭电 4907 Task schedule ·

    Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务. 有m个询问,每个询问有一个数字q,表示如果在q时间有一个工作表之 ...