题目描述
又到暑假了,住在城市 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;
}