试题 算法训练 Car的旅行路线
提交此题 评测记录
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一 条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
输入格式
的第一行有四个正整数s,t,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个城市中任意三个机场的坐标,T I为第I个城市高速铁路单位里程的价格。
输出格式
共有n行,每行一个数据对应测试数据,保留一位小数。
样例输入
1
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
样例输出
47.55
数据规模和约定
0<S<=100,
解题思路:传统的Dijkstra算法解题,只不过数据的初始化(初始化每条路径)比较繁琐,如何初始化(比如,已知矩形三点坐标 ,求第四点坐标。。。)思考时间长,代码量巨大。 把每个机场看做一个点,A城到B城最少费用,等价于,A城机场(择优四选一) 到 B城机场(择优四选一)最少的费用,先数据初始化,然后就是Dijkstra 算法遍历(共4轮)A城4个机场的B城的最少费用,最后四选一求最优值。
By the way,题目的样例输入的s错了,很明显应该是3 。还有样例输出也错了,题目的要求是保留一位小数,明显47.55错了,应该是47.5 。
代码如下:
#include <iostream>
#include <vector>
#include <cmath>
#include <string.h>
using namespace std;
#define INF 65535
struct Airport{
int x,y;
int cityNO;
int NO;
Airport(){ }
Airport(int xx,int yy,int cn,int nn):x(xx),y(yy),cityNO(cn),NO(nn){ }
}AP[410];
struct Way{
int V2;
double W;
Way(){ }
Way(int vv,double ww):V2(vv),W(ww){ }
};
vector< vector<Way> > G(410);
int s,t,A,B;
double dist[410];
int collected[410];
int cnt=1;
double getDist(Airport A1,Airport A2){
double d=(A1.x-A2.x)*(A1.x-A2.x)+(A1.y-A2.y)*(A1.y-A2.y);
return sqrt(d);
}
Airport add4thAP(Airport A1,Airport A2,Airport A3){ //找第四个机场坐标
double D12=getDist(A1,A2);
double D13=getDist(A1,A3);
double D23=getDist(A2,A3);
if(D12>D13 && D12>D23){// D12 为直角三角形的斜边
int cx=A1.x+A2.x;
int cy=A1.y+A2.y;
int x4=cx-A3.x;
int y4=cy-A3.y;
Airport A4(x4,y4,A1.cityNO,cnt++);
return A4;
}
if(D13>D12 && D13>D23){//D13 为直角三角形的斜边
int cx=A1.x+A3.x;
int cy=A1.y+A3.y;
int x4=cx-A2.x;
int y4=cy-A2.y;
Airport A4(x4,y4,A1.cityNO,cnt++);
return A4;
}
if(D23>D12 && D23>D13){//D23 为直角三角形的斜边
int cx=A2.x+A3.x;
int cy=A2.y+A3.y;
int x4=cx-A1.x;
int y4=cy-A1.y;
Airport A4(x4,y4,A1.cityNO,cnt++);
return A4;
}
}
void linkWayInCity(Airport A1,Airport A2,Airport A3,Airport A4,int Ti){
//1、以为起点A1向其他三点 建路
G[A1.NO].push_back(Way(A2.NO,Ti*getDist(A1,A2)));
G[A1.NO].push_back(Way(A3.NO,Ti*getDist(A1,A3) ));
G[A1.NO].push_back(Way(A4.NO,Ti*getDist(A1,A4) ));
G[A2.NO].push_back(Way(A1.NO,Ti*getDist(A2,A1) ));
G[A2.NO].push_back(Way(A3.NO,Ti*getDist(A2,A3) ));
G[A2.NO].push_back(Way(A4.NO,Ti*getDist(A2,A4) ));
G[A3.NO].push_back(Way(A1.NO,Ti*getDist(A3,A1) ));
G[A3.NO].push_back(Way(A2.NO,Ti*getDist(A3,A2) ));
G[A3.NO].push_back(Way(A4.NO,Ti*getDist(A4,A3) ));
G[A4.NO].push_back(Way(A1.NO,Ti*getDist(A1,A4) ));
G[A4.NO].push_back(Way(A2.NO,Ti*getDist(A2,A4) ));
G[A4.NO].push_back(Way(A3.NO,Ti*getDist(A4,A3) ));
}
void ReadInput(){
cin>>s>>t>>A>>B;
for(int i=1;i<=s;i++){
int xi1,yi1,xi2,yi2,xi3,yi3,Ti;
cin>>xi1>>yi1>>xi2>>yi2>>xi3>>yi3>>Ti;
Airport A1(xi1,yi1,i,cnt++);
AP[A1.NO]=A1;
Airport A2(xi2,yi2,i,cnt++);
AP[A2.NO]=A2;
Airport A3(xi3,yi3,i,cnt++);
AP[A3.NO]=A3;
Airport A4=add4thAP(A1,A2,A3);
AP[A4.NO]=A4;
if(i!=A && i!=B)
linkWayInCity(A1,A2,A3,A4,Ti);
}
}
void addAirWay(int city,int pos){
int curNO=(city-1)*4;
int curPos=(pos-1)*4;
G[curNO+1].push_back(Way(curPos+1,t*getDist(AP[curNO+1],AP[curPos+1])));
G[curNO+1].push_back(Way(curPos+2,t*getDist(AP[curNO+1],AP[curPos+2])));
G[curNO+1].push_back(Way(curPos+3,t*getDist(AP[curNO+1],AP[curPos+3])));
G[curNO+1].push_back(Way(curPos+4,t*getDist(AP[curNO+1],AP[curPos+4])));
G[curNO+2].push_back(Way(curPos+1,t*getDist(AP[curNO+2],AP[curPos+1])));
G[curNO+2].push_back(Way(curPos+2,t*getDist(AP[curNO+2],AP[curPos+2])));
G[curNO+2].push_back(Way(curPos+3,t*getDist(AP[curNO+2],AP[curPos+3])));
G[curNO+2].push_back(Way(curPos+4,t*getDist(AP[curNO+2],AP[curPos+4])));
G[curNO+3].push_back(Way(curPos+1,t*getDist(AP[curNO+3],AP[curPos+1])));
G[curNO+3].push_back(Way(curPos+2,t*getDist(AP[curNO+3],AP[curPos+2])));
G[curNO+3].push_back(Way(curPos+3,t*getDist(AP[curNO+3],AP[curPos+3])));
G[curNO+3].push_back(Way(curPos+4,t*getDist(AP[curNO+3],AP[curPos+4])));
G[curNO+4].push_back(Way(curPos+1,t*getDist(AP[curNO+4],AP[curPos+1])));
G[curNO+4].push_back(Way(curPos+2,t*getDist(AP[curNO+4],AP[curPos+2])));
G[curNO+4].push_back(Way(curPos+3,t*getDist(AP[curNO+4],AP[curPos+3])));
G[curNO+4].push_back(Way(curPos+4,t*getDist(AP[curNO+4],AP[curPos+4])));
}
void initAirWay(){
for(int i=1;i<=s;i++){
for(int j=1;j<=s;j++){
if(j!=i ){
addAirWay(i,j);
}
}
}
}
int findMinDist(int NO){
double thismin=INF;
int pos=-1;
for(int i=0;i<G[NO].size();i++){
int next=G[NO][i].V2;
double curW=G[NO][i].W;
if( collected[next]==0 && curW<thismin){
thismin=curW;
pos=next;
}
}
return pos;
}
double Dijkstra(int ANO){
//初始化dist
for(int i=1;i<s*4;i++){
if(i<(A-1)*4+1 && i>(A*4) ){
dist[i]=INF;
}
else{
dist[i]=0;
}
}
memset(collected,0,sizeof(collected));
for(int i=0;i<G[ANO].size();i++){
int next=G[ANO][i].V2;
dist[next]=G[ANO][i].W;
}
while(1){
int V=findMinDist(ANO);
if(V==-1)
break;
collected[V]=1;
for(int i=0;i<G[V].size();i++){
int V2=G[V][i].V2;
if(dist[V]+G[V][i].W<dist[V2]){
dist[V2]=dist[V]+G[V][i].W;
//collected[V2]=1;
}
}
}
double res=min( min(dist[(B-1)*4+1],dist[(B-1)*4+2]),min(dist[(B-1)*4+3],dist[B*4] ));
return res;
}
int main(int argc, char** argv) {
ReadInput();
if(A==B){
cout<<"0.0"<<endl;
}
else{
initAirWay();
double D1=Dijkstra( A*4-3 );
double D2=Dijkstra( A*4-2 );
double D3=Dijkstra( A*4-1 );
double D4=Dijkstra( A*4 );
double res=min( min(D1,D2),min(D3,D4) );
printf("%0.1lf\n",res);
}
// cout<<res<<endl;
// for(int i=1;i<=s*4;i++){
// cout<<"机场坐标:("<<AP[i].x<<","<<AP[i].y<<") city:"<<AP[i].cityNO<<endl;
// }
return 0;
}