zoukankan      html  css  js  c++  java
  • 蓝桥---Car的旅行路线 (预处理+最短路径)

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

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

    题目描述

    图例(从上而下)

    机场
    高速铁路
    飞机航线

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

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

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

    输入格式

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

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

    接下来有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
    ",ans);
    133     return 0;
    134 }
  • 相关阅读:
    蓝桥杯 奇怪的比赛
    历届试题 古堡算式
    PAT 甲级 1040 Longest Symmetric String (25 分)(字符串最长对称字串,遍历)
    PAT 甲级 1039 Course List for Student (25 分)(字符串哈希,优先队列,没想到是哈希)*...
    PAT 甲级 1038 Recover the Smallest Number (30 分)(思维题,贪心)
    PAT 甲级 1037 Magic Coupon (25 分) (较简单,贪心)
    那不是Bug,是新需求
    看看C# 6.0中那些语法糖都干了些什么(上篇)
    eclipse工具的使用心得
    送给那些刚进公司工作滴童鞋
  • 原文地址:https://www.cnblogs.com/jiamian/p/11766479.html
Copyright © 2011-2022 走看看