Car的旅行路线 luogu P1027 (Floyd玄学Bug有点毒瘤)
Car的旅行路线
问题描述
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
S表示城市的个数,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个城市中任意三个机场的坐标,Tl为第I个城市高速铁路单位里程的价格。
1 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3

题目中让我们求出从城市A到城市B的最小花费。
不难看出,这是一道最短路的问题,将最小花费看作每条边的长度,用SPFA(Floyd)跑最短路即可。
然而,每个城市有4个机场,去每个机场的花费都不一样。因此,考虑将一个城市拆分成4个点,在存点的时候储存下城市编号(类似强联通编号),进行特判就好了。
如果是同一个城市的,边长以为铁路票价 * dis, 不同城市则为 plane * dis。
答案即为终点四个机场中最小的。
(勾股定理好评!)
#include <bits/stdc++.h>
using namespace std;
#define N 401
#define isdigit(c) ((c)>='0'&&(c)<='9')
#define min(a,b) ((a)>(b)?(b):(a))
/*比 STL 快?*/ inline int read(){
int x = , s = ;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -;
c = getchar();
}
while(isdigit(c)){
x = (x << ) + (x << ) + (c ^ '');
c = getchar();
}
return x * s;
} struct node{//存每个机场的信息
int x, y;
int city, price;
} t[N << ];
double d[N << ];
int n, pla_pri, s, ht; inline int square(int x){
return x * x;
} inline int dis(int a, int b){//暂时先不开根号,使用起来方便一些
return square(t[a].x - t[b].x) + square(t[a].y - t[b].y); //编号机场的距离
} inline void get4(int n1,int n2,int n3){
int x4, y4;
int x1 = t[n1].x, y1 = t[n1].y, x2 = t[n2].x, y2 = t[n2].y, x3 = t[n3].x, y3 = t[n3].y;
int ab = dis(n1, n2);
int ac = dis(n1, n3);
int bc = dis(n2, n3);
if(ab == ac + bc) x4 = x1 + x2 - x3, y4 = y1 + y2 - y3;//勾股定理,求出第四个点
else if(ac == ab + bc) x4 = x1 + x3 - x2, y4 = y1 + y3 - y2;
else if(bc == ac + ab) x4 = x2 + x3 - x1, y4 = y2 + y3 - y1;
t[n3+].x = x4, t[n3+].y = y4;
/* printf("x1:%d y1: %d x2: %d y2: %d x3: %d y3: %d x4: %d y4: %d\n", x1,y1,x2,y2,x3,y3,x4,y4);
分段检查程序可以防止写完之后 Debug 两小时 */
return ;
} void init(){
int cac_city = ;
for(int i = ;i <= (n << ); i += ){
t[i].x = read(), t[i].y = read();
t[i+].x = read(), t[i+].y = read();
t[i+].x = read(), t[i+].y = read();
t[i].price = t[i+].price = t[i+].price = t[i+].price = read();//把价格记录下来
t[i].city = t[i+].city = t[i+].city = t[i+].city = ++cac_city;//城市记录下来
get4(i, i+, i+);//寻找第四个点
}
return ;
} queue <int> q;
bool vis[N << ]; void spfa(){
/*时刻不忘 n 是4倍!!不然玄学错误!!*/
for(int i = ;i <= (n << ); i++)
d[i] = 99999999.99;
for(int i = * (s - ) + ;i <= * (s - ) + ; i++){//都能作为起点,所以4个点全部推进去
vis[i] = ;
q.push(i);
d[i] = ;
}
while(!q.empty()){//SPFA
int now = q.front();q.pop();
vis[now] = ;
for(int i = ;i <= (n << ); i++){//反正全部有连边,直接 for 循环不香吗
if(i == now)continue;
double cost;
if(t[i].city == t[now].city){//如果在同一个城市
cost = t[i].price * (double)sqrt((double)dis(i, now));
}
else cost = pla_pri * (double)sqrt((double)dis(i, now));//连边的价值(距离)
if(d[i] > d[now] + cost){
d[i] = d[now] + cost;
if(!vis[i]){
vis[i] = ;
q.push(i);
}
}
}
}
return ;
} int main(){
// freopen("hh.txt", "r", stdin);
int T = read();
while(T--){
n = read(), pla_pri = read(), s = read(), ht = read();
if(s == ht){ //这里用SPFA可以不特判,但是如果用Floyd就要特判了 (初始化成了极大值)
puts("0.0");
continue;
}
init();
spfa();
double ans = ~0u >> ;
for(int i = * (ht - ) + ;i <= * (ht - ) + + ; i++)
ans = min(d[i], ans);//答案为终点四个机场里面最小的
printf("%.1lf\n", ans);
}
return ;
}
Car的旅行路线 luogu P1027 (Floyd玄学Bug有点毒瘤)的更多相关文章
- 洛谷P1027 Car的旅行路线
洛谷P1027 Car的旅行路线 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速 ...
- 洛谷 P1027 Car的旅行路线
P1027 Car的旅行路线 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路 ...
- 洛谷 P1027 Car的旅行路线 最短路+Dijkstra算法
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1027 Car的旅行路线 题目描述 又到暑假了,住在 ...
- AC日记——Car的旅行路线 洛谷 P1027
Car的旅行路线 思路: 这题不难,就是有点恶心: 而且,请认真读题目(就是题目卡死劳资): 来,上代码: #include <cmath> #include <cstdio> ...
- P1027 car的旅行路线
car的旅行路线 洛谷链接 这个题关键就是 如何把每个点表示出来,其实求出四个点的坐标后,只需要把这些点连接起来,用一遍folyed求出最短路径就好了. 代码: #include<cmath&g ...
- NOIP2001 Car的旅行路线
题四 Car的旅行路线(30分) 问题描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速 ...
- [NOIP2001提高组]CODEVS1014 Car的旅行路线(最短路)
最短路,这个不难想,但是要为它加边就有点麻烦..还好写完就过了(虽然WA了一次,因为我调试用的输出没删了..),不然实在是觉得挺难调的.. ------------------------------ ...
- GDOI2015小Z的旅行路线
GDOI2015小Z的旅行路线 题意: \(n\)个点的无根树,边上有权值. \(q\)个询问\(s\)和\(s\),问从\(s\)出发,找一条最长路(不经过重复点),保证路径上所有边边权不超过\(x ...
- 【Foreign】旅行路线 [倍增]
旅行路线 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 3 2 ...
随机推荐
- Vxlan L2
VXLAN(Virtual eXtensible LAN可扩展虚拟局域网)诞生了,基于IP网络之上,采用的是MAC in UDP技术 跨三层实现二层通信 总结为何需要Vxlan: 虚拟机规模受到网络规 ...
- Haporxy
安装Haproxy: 下载 wget https://fossies.org/linux/misc/haproxy-1.8.3.tar.gz tar -zxf haproxy-.tar.g cd ha ...
- C :uthash
参考: [1] uthash | 学步园 [2] 源码 [3] 官方文档 [4] [5] 一.哈希表的概念及作用 在一般的线性表或者树中,我们所储存的值写它的存储位置的关系是随机的.因此,在查找过程中 ...
- 线段树 区间加 gcd 差分 小阳的贝壳
小阳的贝壳 如果线段树要维护区间gcd 这个很简单,但是如果有了区间加,维护gcd 就比较麻烦了. 这个首先可以证明的是 gcd(x,y,z)=gcd(x,y-x,z-y) 这个可以推到 n 个 ...
- Mysql数据库多表联查
内连接:查询的是多个表的交集 外连接:查询的是一张表的全部数据和另一张表满足要求的数据 student数据库表 grade数据库表 内连接: 隐式内连接 SELECT s.id, s. NAME, s ...
- 06_CSS入门和高级技巧(4)
复习 CSS : 负责样式层,层叠式样式表cascading style sheet.CSS2.1,最新版本CSS3. CSS选择器: 选择哪些元素加样式.基本选择3种:标签p.id选择器#id.cl ...
- 玩好百家乐需要掌握些什么技巧和打法?来自ag老玩家的实战经验心得总结
最近很多网友给我留言,说为什么学了很多技巧和打法这个游戏还是玩不好,坦白说,其实bjl想要玩得好,不是说你懂得多少技巧和掌握了多少种打法就可以的了,而是你要懂得如何把这些正确结合去运用,这些我之前都强 ...
- python语法学习第十一天--迭代器
迭代:类似循环,这一次的值作为下一次迭代的开始值 BIF:iter():将某个可以作为迭代器的容器变为迭代器 next():做下一次迭代 当next()到最后一个时,抛出StopIteration ...
- 设计模式之GOF23状态模式
状态模式state 场景:当具有许多状态并且需要频繁改变时,用这种模式 -电梯的运行:维修,正常,自动关门,自动开门,向上运行,向下运行,消防状态 -红绿灯:红灯,黄灯,绿灯 -企业或政府系统:公文的 ...
- CSS理论:margin-left在float中的运用
源码如下: margin-left 指的是左边的外边距,为正数时,左边间距增大,div向右偏移,为负数时,左边间距减少,相反往左偏移 双飞翼 .wrap { width: 100%; margin: ...