> 文章列表 > P1027 [NOIP2001 提高组] Car 的旅行路线

P1027 [NOIP2001 提高组] Car 的旅行路线

P1027 [NOIP2001 提高组] Car 的旅行路线

题目描述

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

图例(从上而下)

机场
高速铁路
飞机航线

注意:图中并没有标出所有的铁路与航线。

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

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

输入格式

第一行为一个正整数 �n,表示有 �n 组测试数据。

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

�S 表示城市的个数,�t 表示飞机单位里程的价格,�A,�B 分别为城市A,B 的序号。

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

输出格式

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

输入输出样例

输入 #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

说明/提示

【数据范围】
对于 100%100% 的数据,1≤�≤101≤n≤10,1≤�≤1001≤S≤100,1≤�,�≤�1≤A,B≤S

【题目来源】

NOIP 2001 提高组第四题

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = 4010;
struct infor {int x,y;int num;
} city[maxn];
int sub[maxn];
int map[maxn][maxn];
double dp[maxn][maxn];
double dist[maxn][maxn];
void add(int cnt) {int x1,x2,x3,y1,y2,y3;x1 = city[cnt-2].x;x2 = city[cnt-1].x;x3 = city[cnt].x;y1 = city[cnt-2].y;y2 = city[cnt-1].y;y3 = city[cnt].y;int k;int cx,cy;for(int i=1; i<=3; i++) {if(i==1) {if(x1==x2 && y1==y3) {cx = x3-x1;city[++cnt].x = x2+cx;city[cnt].y = y2;city[cnt].num = city[cnt-1].num;return ;} else if(x1==x3 && y1==y2) {cx = x2-x1;city[++cnt].x = x3+cx;city[cnt].y = y3;city[cnt].num = city[cnt-1].num;return ;} else if(x1==x2 || x1==x3) continue;k = ((y2-y1)*(y3-y1))/((x2-x1)*(x3-x1));if(k==-1) {cx = x1-x2;cy = y1-y2;city[++cnt].x = x3-cx;city[cnt].y = y3-cy;city[cnt].num = city[cnt-1].num;return ;}} else if(i==2) {if(x2==x1 && y2==y3) {cx = x3-x2;city[++cnt].x = x2+cx;city[cnt].y = y1;city[cnt].num = city[cnt-1].num;return ;} else if(x2==x3 && y2==y1) {cx = x1-x2;city[++cnt].x = x2+cx;city[cnt].y = y3;city[cnt].num = city[cnt-1].num;return ;} else if(x2==x1||x2==x3) continue;k = ((y1-y2)*(y3-y2))/((x1-x2)*(x3-x2));if(k==-1) {cx = x2-x1;cy = y2-y1;city[++cnt].x = x3-cx;city[cnt].y = y3-cy;city[cnt].num = city[cnt-1].num;return ;}} else if(i==3) {if(x3==x1 && y3==y2) {cx = x2-x3;city[++cnt].x = x1+cx;city[cnt].y = y1;city[cnt].num = city[cnt-1].num;return ;} else if(x3==x2 && y3==y1) {cx = x1-x3;city[++cnt].x = x2+cx;city[cnt].y = y2;city[cnt].num = city[cnt-1].num;return ;} else if(x3==x1 || x3==x2) continue;k = ((y1-y3)*(y2-y3))/((x1-x3)*(x2-x3));if(k==-1) {cx = x3-x1;cy = y3-y1;city[++cnt].x = x2-cx;city[cnt].y = y2-cy;city[cnt].num = city[cnt-1].num;return ;}}}
}
double dis(int a,int b) {int x1 = city[a].x;int x2 = city[b].x;int y1 = city[a].y;int y2 = city[b].y;double ans = 0;ans = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));return ans;
}
double floyed(int n,int t,int a,int b) {n = 4*n;for(int i=1; i<=4*n; i++) {for(int j=1; j<=4*n; j++) {dist[i][j] = dis(i,j);}}for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {if(i==j) dp[i][j] = 0;else {if(city[i].num == city[j].num) {dp[i][j] = dist[i][j] * sub[city[i].num];} else dp[i][j] = dist[i][j] * t;}}}for(int k=1; k<=n; k++) {for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);}}}double ans = 0x7f7f7f7f;for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {if(city[i].num==a&&city[j].num==b) {ans = min(ans,dp[i][j]);}}}return ans;
}
int main() {int T;cin >> T;while(T--) {memset(sub,0,sizeof(sub));int n,t,a,b;int cnt = 1;cin >> n >> t >> a >> b;for(int i=1; i<=n; i++) {cin >> city[cnt].x >> city[cnt].y;city[cnt++].num = i;cin >> city[cnt].x >> city[cnt].y;city[cnt++].num = i;cin >> city[cnt].x >> city[cnt].y;city[cnt].num = i;cin >> sub[i];add(cnt);cnt+=2;}memset(map,0,sizeof(map));for(int i=1; i<=cnt; i++) {int x = city[i].x;int y = city[i].y;int num = city[i].num;map[x][y] = num;}double ans = floyed(n,t,a,b);printf("%.1lf\\n",ans);}return 0;
}