Car的旅行路线
Car的旅行路线
https://ac.nowcoder.com/acm/problem/16697
题目描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
图例(从上而下)
机场
高速铁路
飞机航线
注意:图中并没有标出所有的铁路与航线。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
任务:找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
输入描述:
第一行为一个正整数n( 0 ≤ n ≤ 10 ),表示有n组测试数据。
每组的第一行有4个正整数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个城市中任意3个机场的坐标,Ti 为第i个城市高速铁路单位里程的价格。
输出描述:
共有n行,每行1个数据对应测试数据(最小花费)。保留一位小数。
题解
对于本题数据范围着实很小。我们直接建一个图然后跑最短路就好了。
可能只有建图写着比较麻烦吧,应该算是一个最短路裸题。具体细节看代码注释吧
代码
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pii pair<int,int>
#define all(A) A.begin(), A.end()
#define fi first
#define se second
#define MP make_pair
#define rep(i,n) for(register int i=0;i<(n);++i)
#define repi(i,a,b) for(register int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(register int i=int(b);i>=(a);--i)
template<typename T>
inline T read(){
T s=0,f=1; char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f=-1;ch = getchar();}
while(isdigit(ch)) {s=(s<<3)+(s<<1)+ch-48;ch = getchar();}
return s*f;
}
#define gn() read<int>()
#define gl() read<ll>()
template<typename T>
inline void print(T x) {
if(x<0) putchar('-'), x=-x;
if(x>9) print(x/10);
putchar(x%10+'0');
}
////////////////////////////////////////////////////////////////////////
const int N=2e5+100;
struct point{
double x, y;
int id;
}v[450];
vector<pair<int,double> > t[450];
double powdis(point a,point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int T[105];
double dis[440];
int tot=0;
int s,tt,a,b;
double dij(){
priority_queue<pair<double,int> >Q;
for(int i=(a-1)*4+1;i<=a*4;++i){
Q.push({0,i});
dis[i]=0;
}
double ans=1e9;
while(!Q.empty()){
pair<double,int> now=Q.top();
Q.pop();
if(v[now.se].id==b){
ans=min(ans,dis[now.se]);
}
for(auto k:t[now.se]){
if(dis[k.fi]>dis[now.se]+k.se){
dis[k.fi]=dis[now.se]+k.se;
//cout<<"dis["<<k.fi<<"]="<<dis[k.fi]<<endl;
Q.push({-dis[k.fi],k.fi});
}
}
}
return ans;
}
void solve(){
s=gn(),tt=gn(),a=gn(),b=gn();
repi(i,1,s){
repi(j,1,3){
++tot;
scanf("%lf%lf",&v[tot].x,&v[tot].y);
v[tot].id=i;
}
scanf("%d",&T[i]);
double ab=powdis(v[tot-2],v[tot-1]);
double ac=powdis(v[tot-2],v[tot]);
double bc=powdis(v[tot-1],v[tot]);
if(ab+ac==bc){
double x=v[tot-1].x+v[tot].x-v[tot-2].x;
double y=v[tot-1].y+v[tot].y-v[tot-2].y;
v[++tot]={x,y,i};
}
else if(ab+bc==ac){
double x=v[tot-2].x+v[tot].x-v[tot-1].x;
double y=v[tot-2].y+v[tot].y-v[tot-1].y;
v[++tot]={x,y,i};
}
else {
double x=v[tot-1].x+v[tot-2].x-v[tot].x;
double y=v[tot-1].y+v[tot-2].y-v[tot].y;
v[++tot]={x,y,i};
}//求出第四个点
repr(j,tot,tot-3){
repi(k,tot-3,tot){
if(j!=k)t[j].pb(MP(k,sqrt(powdis(v[j],v[k]))*T[i]));
}
}//把相同城市之间的高铁航道建好
}
for(int i=1;i<=tot;++i){
dis[i]=1e9;
for(int j=1;j<=tot;++j){
if(v[i].id==v[j].id)continue;
t[i].pb(MP(j,sqrt(powdis(v[i],v[j]))*tt));
}
}//把不同城市之间的飞机航道建好
printf("%.1f\n",dij());//跑最短路
}
////////////////////////////////////////////////////////////////////////
int main(){
int t;
t=gn();
while(t--)
solve();
}
/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/杂题题解 文章被收录于专栏
各种各样题目的题解
查看7道真题和解析