洛谷 P1027 Car的旅行路线

题目描述

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

图例(从上而下)

机场
高速铁路
飞机航线

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

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

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

输入输出格式

输入格式:

 

第一行为一个正整数 nn ( 0 \le n \le 100n10 ),表示有 nn 组测试数据。

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

SS ( 0<S \le 1000<S100 )表示城市的个数, tt 表示飞机单位里程的价格, AA , BB 分别为城市 AA , BB 的序号,( 1 \le A1A, B \le SBS )。

接下来有 SS 行,其中第 II 行均有 77 个正整数 xi_1,yi_1,xi_2,yi_2,xi_3,yi_3,Tixi1,yi1,xi2,yi2,xi3,yi3,Ti ,这当中的( xi_1,yi_1xi1,yi1 ),( xi_2,yi_2xi2,yi2),( xi_3,yi_3xi3,yi3 )分别是第 ii 个城市中任意 33 个机场的坐标, TiTi 为第 ii 个城市高速铁路单位里程的价格。

 

输出格式:

 

共有 nn 行,每行 11 个数据对应测试数据。 保留一位小数。

 

输入输出样例

输入样例#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.5
思路:转化成图之后跑spfa。
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
queue<int>que;
int vis[410];
double ans=0x7f7f7f7f;
int n,s,t,a,b,tot,sum;
double cap[160010],dis[410];
int to[160010],net[160010],head[410];
struct nond{
    int x[5],y[5],num[5];
    double t;
}v[110];
struct none{ int l,r; };
void add(int u,int v,double w){
    to[++tot]=v;cap[tot]=w;net[tot]=head[u];head[u]=tot;
    to[++tot]=u;cap[tot]=w;net[tot]=head[v];head[v]=tot;
}
none find(int p){
    none tmp;
    double maxn=-99999;
    for(int i=1;i<=3;i++)
        for(int j=i+1;j<=3;j++){
            double x=(v[p].x[i]-v[p].x[j])*(v[p].x[i]-v[p].x[j])+(v[p].y[i]-v[p].y[j])*(v[p].y[i]-v[p].y[j]);
            if(x>maxn){ maxn=x; tmp.l=i;tmp.r=j; }
        }
    return tmp;
}
int findx(int p){
    none tmp=find(p);int k;
    if(tmp.l==1&&tmp.r==2||tmp.l==2&&tmp.r==1)    k=3;
    else if(tmp.l==1&&tmp.r==3||tmp.l==3&&tmp.r==1)    k=2;
    else if(tmp.l==2&&tmp.r==3||tmp.l==3&&tmp.r==2)    k=1;
    return v[p].x[tmp.l]+v[p].x[tmp.r]-v[p].x[k];
}
int findy(int p){
    none tmp=find(p);int k;
    if(tmp.l==1&&tmp.r==2||tmp.l==2&&tmp.r==1)    k=3;
    else if(tmp.l==1&&tmp.r==3||tmp.l==3&&tmp.r==1)    k=2;
    else if(tmp.l==2&&tmp.r==3||tmp.l==3&&tmp.r==2)    k=1;
    return v[p].y[tmp.l]+v[p].y[tmp.r]-v[p].y[k];
}
void build(){
    for(int i=1;i<=s;i++){
        for(int a=1;a<=4;a++){
            for(int b=a+1;b<=4;b++){
                double x=sqrt((v[i].x[a]-v[i].x[b])*(v[i].x[a]-v[i].x[b])+(v[i].y[a]-v[i].y[b])*(v[i].y[a]-v[i].y[b]))*v[i].t;
                add(v[i].num[a],v[i].num[b],x);
            }
        }
        for(int j=i+1;j<=s;j++)
            for(int a=1;a<=4;a++){
                for(int b=1;b<=4;b++){
                    double x=t*sqrt((v[i].x[a]-v[j].x[b])*(v[i].x[a]-v[j].x[b])+(v[i].y[a]-v[j].y[b])*(v[i].y[a]-v[j].y[b]));
                    add(v[i].num[a],v[j].num[b],x);
                }
            }
    }
}
void spfa(int s){
    memset(vis,0,sizeof(vis));
    memset(dis,0x7f,sizeof(dis));
    while(!que.empty())    que.pop();
    que.push(s);dis[s]=0;vis[s]=1;
    while(!que.empty()){
        int now=que.front();
        que.pop();vis[now]=0;
        for(int i=head[now];i;i=net[i])
            if(dis[to[i]]>dis[now]+cap[i]){
                dis[to[i]]=dis[now]+cap[i];
                if(!vis[to[i]]){
                    vis[to[i]]=1;
                    que.push(to[i]);
                }
            }
    }
}
int main(){
    scanf("%d",&n);
    while(n--){
        scanf("%d%d%d%d",&s,&t,&a,&b);
        for(int i=1;i<=s;i++){
            int x1,y1,x2,y2,x3,y3,x4,y4,t;
            scanf("%d%d%d%d%d%d%lf",&v[i].x[1],&v[i].y[1],&v[i].x[2],&v[i].y[2],&v[i].x[3],&v[i].y[3],&v[i].t);
            v[i].x[4]=findx(i);v[i].y[4]=findy(i);
            for(int j=1;j<=4;j++)    v[i].num[j]=++sum;
        }
        build();
        for(int i=1;i<=4;i++){
            spfa(v[a].num[i]);
            ans=min(ans,min(dis[v[b].num[1]],min(dis[v[b].num[2]],min(dis[v[b].num[3]],dis[v[b].num[4]]))));
        }
        printf("%.1lf",ans);
        ans=0x7f7f7f7;
    }
}

 

 
posted @ 2018-07-20 11:05  一蓑烟雨任生平  阅读(232)  评论(0编辑  收藏  举报