Car的旅行路线

描述

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

那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。

img

格式

输入格式

第一行有四个正整数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个城市中任意三个机场的坐标,T I为第I个城市高速铁路单位里程的价格。

输出格式

输出最小费用(结果保留两位小数)

样例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.55

限制

每个测试点1s

来源

NOIP2001第四题

  题不难,但相当考验编程能力,,这题在考场上要有耐心

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<vector>
  8 #include<queue>
  9 #include<fstream>
 10 using namespace std;
 11 const int inf=1e9;
 12 int N,city_num,S,T;
 13 int fly_cost;
 14 int tot;
 15 struct node{
 16     int x[5],y[5];
 17 }Airport[200];
 18 int road_cost[200];
 19 int vis[200][200];
 20 int to[200][200];
 21 double cost[200][200];
 22 double ANS;
 23 int min1(double a1,double a2){
 24     if(a1<a2) return a1;
 25     else return a2;
 26 }
 27 void calc_roadcost(int xx){//计算机场之间的铁路费用,xx表示机场标号 
 28     
 29     for(int i=1;i<=4;i++){//机场标号
 30         int u=4*(xx-1)+i;//在图中代表的点的标号
 31         for(int j=1;j<=4;j++){//机场标号
 32             int v=4*(xx-1)+j;//在图中代表的点的标号
 33             if(u!=v&&vis[u][v]==0&&vis[v][u]==0){//如果不是同一个点,且没有建立过连接
 34                 vis[u][v]=1; vis[v][u]=1;
 35                 int e=++to[u][0]; 
 36                 int r=++to[v][0];
 37                 to[u][e]=v; to[v][r]=u;
 38                 
 39                 double dis=((double)Airport[xx].x[i]-(double)Airport[xx].x[j])*((double)Airport[xx].x[i]-(double)Airport[xx].x[j])+
 40                            ((double)Airport[xx].y[i]-(double)Airport[xx].y[j])*((double)Airport[xx].y[i]-(double)Airport[xx].y[j]);
 41                 dis=sqrt(dis);
 42                 dis*=(double)road_cost[xx];
 43                 cost[u][e]=dis; cost[v][r]=dis;
 44             }
 45         }
 46     }
 47     
 48 }
 49 
 50 void calc_fly_cost(){//计算机场之间的航线费用
 51 
 52     for(int i=1;i<=city_num;i++){//城市标号
 53         for(int j=1;j<=4;j++){//城市中的机场
 54             int u=4*(i-1)+j;//此机场在图中的标号
 55             for(int k=1;k<=city_num;k++){//城市标号
 56                 if(k!=i){//保证不是同一个城市
 57                     for(int t=1;t<=4;t++){//城市中的机场
 58                         int v=4*(k-1)+t;//此机场在图中的标号
 59                         
 60                         if(vis[u][v]==0&&vis[v][u]==0){//没有建立过连接
 61                             vis[u][v]=1; vis[v][u]=1;
 62                             int e=++to[u][0];
 63                             int r=++to[v][0];
 64                 
 65                             to[u][e]=v; to[v][r]=u;
 66                             double dis=sqrt(((double)Airport[i].x[j]-(double)Airport[k].x[t])*((double)Airport[i].x[j]-
 67                           (double)Airport[k].x[t])+((double)Airport[i].y[j]-(double)Airport[k].y[t])*
 68                           ((double)Airport[i].y[j]-(double)Airport[k].y[t]));
 69                             dis*=(double)fly_cost;
 70                             cost[u][e]=dis; cost[v][r]=dis;
 71                             
 72                         }
 73                         else continue;
 74                     }
 75                 }
 76                 else continue;
 77             }
 78         }
 79     }
 80 
 81 }
 82 void SPFA(int s){
 83     
 84     static queue<int> Q;
 85     double dis[200];
 86     bool vis2[200];
 87     
 88     for(int i=0;i<=199;i++) dis[i]=(double)inf;
 89     memset(vis2,false,sizeof(vis2));
 90     while(Q.size()>0) Q.pop();
 91     
 92     dis[s]=(double)0;
 93     Q.push(s); vis2[s]=true;
 94     
 95     while(Q.size()>0){
 96         int x=Q.front(); Q.pop();
 97         vis2[x]=false;
 98         for(int i=1;i<=to[x][0];i++){
 99             int y=to[x][i];
100             if(dis[y]>dis[x]+cost[x][i]){
101                 dis[y]=dis[x]+cost[x][i];
102                 if(vis2[y]==false){
103                     vis2[y]=true;
104                     Q.push(y);
105                 }
106             }
107         }
108     }
109     
110     for(int i=1;i<=4;i++){
111         int v=4*(T-1)+i;
112         if(dis[v]<(double)ANS){
113             ANS=dis[v];
114         }
115     }
116     
117 }
118 inline double calc_dis(int x1,int x2,int y1,int y2){//两点间距离的平方 
119     return ((double)x1-(double)x2)*((double)x1-(double)x2)+
120            ((double)y1-(double)y2)*((double)y1-(double)y2);
121 }
122 int main(){
123     scanf("%d%d%d%d",&city_num,&fly_cost,&S,&T);
124     tot=4*city_num;
125     for(int j=1;j<=city_num;j++){
126             scanf("%d%d%d%d%d%d%d",&Airport[j].x[1],&Airport[j].y[1],
127                                    &Airport[j].x[2],&Airport[j].y[2],
128                                    &Airport[j].x[3],&Airport[j].y[3],
129                                    &road_cost[j]);
130             
131         if(calc_dis(Airport[j].x[1],Airport[j].x[2],Airport[j].y[1],Airport[j].y[2])==
132            calc_dis(Airport[j].x[1],Airport[j].x[3],Airport[j].y[1],Airport[j].y[3])+
133            calc_dis(Airport[j].x[2],Airport[j].x[3],Airport[j].y[2],Airport[j].y[3])
134         )//说明 3是直角顶点
135         Airport[j].x[4]=Airport[j].x[1]+Airport[j].x[2]-Airport[j].x[3],
136         Airport[j].y[4]=Airport[j].y[1]+Airport[j].y[2]-Airport[j].y[3];
137         
138         else if(calc_dis(Airport[j].x[1],Airport[j].x[3],Airport[j].y[1],Airport[j].y[3])==
139            calc_dis(Airport[j].x[1],Airport[j].x[2],Airport[j].y[1],Airport[j].y[2])+
140            calc_dis(Airport[j].x[3],Airport[j].x[2],Airport[j].y[3],Airport[j].y[2])
141         )//说明 2是直角顶点
142         Airport[j].x[4]=Airport[j].x[1]+Airport[j].x[3]-Airport[j].x[2],
143         Airport[j].y[4]=Airport[j].y[1]+Airport[j].y[3]-Airport[j].y[2];
144             
145         else if(calc_dis(Airport[j].x[2],Airport[j].x[3],Airport[j].y[2],Airport[j].y[3])==
146            calc_dis(Airport[j].x[2],Airport[j].x[1],Airport[j].y[2],Airport[j].y[1])+
147            calc_dis(Airport[j].x[3],Airport[j].x[1],Airport[j].y[3],Airport[j].y[1])
148         )//说明 1是直角顶点
149         Airport[j].x[4]=Airport[j].x[2]+Airport[j].x[3]-Airport[j].x[1],
150         Airport[j].y[4]=Airport[j].y[2]+Airport[j].y[3]-Airport[j].y[1];
151         
152         calc_roadcost(j);//计算机场之间的铁路费用 
153     }
154     calc_fly_cost();//计算机场之间的航线费用 
155     ANS=inf;
156     for(int i=1;i<=4;i++){
157         int from=4*(S-1)+i;
158         SPFA(from);
159     }
160     printf("%.2f",ANS);
161     return 0;
162 }
原文地址:https://www.cnblogs.com/CXCXCXC/p/4822128.html