洛谷 P1027 Car的旅行路线

洛谷 P1027 Car的旅行路线


题目

题目描述

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

这里写图片描述

图例(从上而下)

机场 高速铁路

飞机航线

  注意:图中并没有

标出所有的铁路与航线。

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

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

输入输出格式

输入格式:
第一行为一个正整数n(0<=n<=10),表示有n组测试数据。

每组的第一行有四个正整数s,t,A,B。

S(0

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.5

题解

Floyd,就是数据构造有点烦


代码

#include<iostream>
#include<cstdio>
#include<cmath>
#define INF 0x7fffffff
#define sqr(x) x*x
using namespace std;

int n,s,tt,a,b;
int x[1005],y[1005],ti[505];
double d[505][505];

void work(int a,int b)
{
    d[a][b]=sqrt(sqr((x[a]-x[b]))+sqr((y[a]-y[b])));
    if (((a-1)/4)==((b-1)/4)) d[a][b]=d[a][b]*ti[(a-1)/4+1];
     else d[a][b]=d[a][b]*tt;
    d[b][a]=d[a][b];
    return;
}

int find(int a,int b,int c)
{
    if ((d[a][b]>d[b][c])&&(d[a][b]>d[a][c])) return c;
    if ((d[a][c]>d[b][c])&&(d[a][c]>d[a][b])) return b;
    if ((d[b][c]>d[a][b])&&(d[b][c]>d[a][c])) return a;
}

void get(int a,int b,int c)
{
    work(a,b);
    work(b,c);
    work(c,a);
    int t=find(a,b,c);
    if (t==a)
    {
        x[c+1]=x[c]+x[b]-x[a];
        y[c+1]=y[c]+y[b]-y[a];
    }
    if (t==b)
    {
        x[c+1]=x[c]+x[a]-x[b];
        y[c+1]=y[c]+y[a]-y[b];
    }
    if (t==c)
    {
        x[c+1]=x[a]+x[b]-x[c];
        y[c+1]=y[a]+y[b]-y[c];
    }
}

int main()
{
    scanf("%d",&n);
    while (n--)
    {
        scanf("%d%d%d%d",&s,&tt,&a,&b);
        int i,j,k;
        for (i=1;i<=505;i++)
         for (j=1;j<=505;j++)
          d[i][j]=INF;
        for (i=1;i<=s;i++)
        {
            scanf("%d%d%d%d%d%d%d",&x[4*i-3],&y[4*i-3],&x[4*i-2],&y[4*i-2],&x[4*i-1],&y[4*i-1],&ti[i]);
            get(4*i-3,4*i-2,4*i-1);
        }
        for (i=1;i<=4*s;i++)
         for (j=1;j<=4*s;j++)
          work(i,j);
        for (k=1;k<=4*s;k++) 
         for (i=1;i<=4*s;i++)
          for (j=1;j<=4*s;j++) 
           if (d[k][j]+d[i][k]<d[i][j]) d[i][j]=d[k][j]+d[i][k];
        double ans=1000000000.0;
        for (i=4*a-3;i<=4*a;i++)
         for (j=4*b-3;j<=4*b;j++)
          if (d[i][j]<ans) ans=d[i][j];
        printf("%.1lf\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值