码迷,mamicode.com
首页 > 其他好文 > 详细

Car的旅行路线 (预处理+最短路径)

时间:2019-10-30 18:33:58      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:div   pac   alt   sub   tom   接下来   iostream   eof   reset   

 

https://www.luogu.org/problem/P1027

 

题目描述

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

技术图片

图例(从上而下)

机场
高速铁路
飞机航线

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

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

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

输入格式

第一行有4个正整数s,t,A,B

S(0<S100)表示城市的个数,tt表示飞机单位里程的价格,A,B分别为城市A,B的序号,(1A,BS)。

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

输出格式

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
输出
47.5

 

 

本题我们不妨把每个城市的4个机场看做四个点。那样这图就有4×s 个点。

根据题目描述,我们又知道:每一个机场都与另外每一个机场互通,差别只是在是否是同一个城市:

如果是,那么只能走高速铁路;

如果不是,那么只能走航道。用一个判断来计算这条路的花费即可。

最后跑最短路,答案为到达城市的4个机场的花费的最小值。

 

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <string>
  5 #include <math.h>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <stack>
  9 #include <queue>
 10 #include <set>
 11 #include <map>
 12 #include <sstream>
 13 const int INF=0x3f3f3f3f;
 14 typedef long long LL;
 15 const int mod=1e9+7;
 16 //const double PI=acos(-1);
 17 #define Bug cout<<"---------------------"<<endl
 18 const int maxn=1e5+10;
 19 using namespace std;
 20 
 21 int n,A,B;
 22 double cost;
 23 
 24 struct node 
 25 {
 26     int x, y;
 27     int city;
 28 };
 29 
 30 node PT[4];
 31 node APT[maxn];
 32 int cntt;
 33 
 34 struct Edge_node
 35 {
 36     int to;
 37     int next;
 38     double cost;
 39 }Edge[7005<<1];
 40 
 41 int head[3000];
 42 int cnt;
 43 double dis[3000];
 44 int ctcost[maxn];
 45 
 46 struct cmp1
 47 {
 48     bool operator()(int x,int y)
 49     {
 50         return dis[x]>dis[y]; 
 51     }
 52 };
 53 
 54 void add_edge(int u,int v,double val)
 55 {
 56     Edge[cnt].to=v;
 57     Edge[cnt].cost=val;
 58     Edge[cnt].next=head[u];
 59     head[u]=cnt++;
 60 } 
 61 
 62 double juli(int x1, int y1, int x2, int y2) 
 63 {
 64     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 
 65 }
 66 
 67 void Dijkstra()
 68 {
 69     fill(dis+1,dis+1+cntt,INF);
 70     priority_queue<int,vector<int>,cmp1 > qe;
 71     for(int i=A*4-3;i<=A*4;i++)
 72     {
 73         dis[i]=0;
 74         qe.push(i);
 75     }
 76     while(!qe.empty())
 77     {
 78         int u=qe.top();
 79         qe.pop();
 80         for(int i=head[u];i!=-1;i=Edge[i].next)
 81         {
 82             int v=Edge[i].to;
 83             if(dis[u]+Edge[i].cost<dis[v])
 84             {
 85                 dis[v]=dis[u]+Edge[i].cost;
 86                 qe.push(v);
 87             }
 88         } 
 89     }
 90 }
 91 
 92 int main()
 93 {
 94     cnt=cntt=0;
 95     memset(head,-1,sizeof(head)); 
 96     scanf("%d %lf %d %d",&n,&cost,&A,&B);
 97     for(int i=1;i<=n;i++)
 98     {
 99         scanf("%d %d %d %d %d %d %d",&PT[0].x,&PT[0].y,&PT[1].x,&PT[1].y,&PT[2].x,&PT[2].y,&ctcost[i]);
100         while((PT[0].x-PT[1].x)*(PT[2].x-PT[1].x)!=(PT[0].y-PT[1].y)*(PT[1].y-PT[2].y))
101         {
102             node t=PT[0];
103             PT[0]=PT[1];PT[1]=PT[2];PT[2]=t;
104         }
105         PT[3].x=PT[2].x+(PT[0].x-PT[1].x);//求出最后一个点 
106         PT[3].y=PT[2].y+(PT[0].y-PT[1].y);
107         for(int k=0;k<4;k++)
108         {
109             PT[k].city=i;
110             APT[++cntt]=PT[k];
111         }
112     }
113     for(int i=1;i<=cntt;i++)//计算每两个点之间的费用
114     {
115         for(int j=i+1;j<=cntt;j++)
116         {
117             double val;
118             if(APT[i].city==APT[j].city)
119                 val=juli(APT[i].x,APT[i].y,APT[j].x,APT[j].y)*ctcost[APT[i].city];
120             else val=juli(APT[i].x,APT[i].y,APT[j].x,APT[j].y)*cost;
121             add_edge(i,j,val);
122             add_edge(j,i,val);
123         }
124     }
125     Dijkstra();//我竟然忘写这个了。。。 
126     double ans=INF;
127     for(int i=B*4-3;i<=B*4;i++)
128     {
129         if(ans>dis[i])
130             ans=dis[i];
131     }
132     printf("%.1f\n",ans);
133     return 0;
134 }

 

Car的旅行路线 (预处理+最短路径)

标签:div   pac   alt   sub   tom   接下来   iostream   eof   reset   

原文地址:https://www.cnblogs.com/jiamian/p/11766479.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!