Car的旅行路线 题解 P1027

题解 Car的旅行路线

题目大意

懒得抄了,太长了,直接放链接吧

Car的旅行路线 Luogu P1027

分析

其实就是写了半天的最短路

我们需要几个东西

首先,要计算每个城市的第四个点

这个要应用一下我们贫乏的初中数学知识

\[设矩形四个顶点的坐标分别为\\A(x_A,y_A),B(x_B,y_B),C(x_C,y_C),D(x_D,y_D) \\且\ \ AC\gt AB \ge BC \\\therefore x_D=x_C+(x_A-x_B),y_D=x_D+(y_A-y_B) \]

我们珂以定义一个二维数组

int city[maxn][9];
//其中city[i][t]的含义解释如下:
/*
i			代表城市id
city[i][1]	x1
city[i][2]	y1
city[i][3]	x2
city[i][4]	y2
city[i][5]	x3
city[i][6]	y3
city[i][7]	x4
city[i][8]	y4
city[i][9]	T
*/

我们珂以比较快速地写出一个计算 city[i][7]city[i][8] 的函数

//计算两点距离
inline double calc(int x1,int y1,int x2,int y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
//处理city[k]
inline void location(int k){
    double l12=calc(city[k][1],city[k][2],city[k][3],city[k][4]);
    double l23=calc(city[k][3],city[k][4],city[k][5],city[k][6]);
    double l13=calc(city[k][1],city[k][2],city[k][5],city[k][6]);
    if(l12>l13&&l12>l23){
        city[k][7]=city[k][3]+city[k][1]-city[k][5];
        city[k][8]=city[k][4]+city[k][2]-city[k][6];
    }else if(l23>l12&&l23>l13){
        city[k][7]=city[k][3]+city[k][5]-city[k][1];
        city[k][8]=city[k][4]+city[k][6]-city[k][2];
    }else{
        city[k][7]=city[k][1]+city[k][5]-city[k][3];
        city[k][8]=city[k][2]+city[k][6]-city[k][4];
    }
}
然后,要把这些数据转化为边

飞机场就是反复循环,计算距离

高铁就在城市内循环就好

for(int i = 1 ; i<=s ; i++){
    //fr()是快读
    //insert()是建边的函数
    city[i][1]=fr();city[i][2]=fr();
    city[i][3]=fr();city[i][4]=fr();
    city[i][5]=fr();city[i][6]=fr();
    location(i);
    city[i][9]=fr();
    GO(1,4,ss)GO(1,4,tt){
        insert(4*(i-1)+ss,4*(i-1)+tt,city[i][9]*calc(city[i][2*ss-1],city[i][2*ss],city[i][2*tt-1],city[i][2*tt]));
    }
}
for(int uci = 1 ; uci<=s ; uci++)for(int up = 1 ; up<=4 ; up++){
    GO(1,s,vci)GO(1,4,vp){
        insert(4*(uci-1)+up,4*(vci-1)+vp,calc(city[uci][up*2-1],city[uci][up*2],city[vci][vp*2-1],city[vci][vp*2])*t);
    }
}
最后,只需要执行4次最短路算法就好了

AC代码

#include <bits/stdc++.h>
using namespace std;
#define GO(__start,__end,__var) for(int __var = __start ; __var<=__end ; __var++)
#define GOGRA(__edge,__head,__start,__var) for(int __var = __head[__start];__var;__var=__edge[__var].next)
const int maxn=1e2 + 12,maxm=1e5 + 12;
typedef long long lld;
typedef double lf;
namespace io{
    inline int fr(){
        register int x=0,dis=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch =='-')dis=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);
            ch = getchar();
        }
        return x*dis;
    }
    inline lld fr_lld(){
        register lld x=0,dis=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch =='-')dis=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);
            ch = getchar();
        }
        return x*dis;
    }
    template<class T> void fw(T num){
        if(num<0){
            putchar('-');
            num=-num;
        }
        if(num>9)fw(num/10);
        putchar(num%10+'0');
    }
    template<class T> void fw(T num,char backch){
    fw(num);putchar(backch);
    }
}
using namespace io;
int len,head[maxn];
struct Edge{int to,next;lf w;}e[maxm];
inline void insert(int u,int v,lf w){
    e[++len]={v,head[u],w};
    head[u]=len;
}

int s,t;
//x1,y1,x2,y2,x3,y3,x4,y4,T
int city[maxn][9];
int a,b;
lf dis[maxn];
bool inq[maxn];
queue<int>q;
inline lf calc(int x1,int y1,int x2,int y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
inline void location(int k){
    lf l12=calc(city[k][1],city[k][2],city[k][3],city[k][4]);
    lf l23=calc(city[k][3],city[k][4],city[k][5],city[k][6]);
    lf l13=calc(city[k][1],city[k][2],city[k][5],city[k][6]);
    if(l12>l13&&l12>l23){
        city[k][7]=city[k][3]+city[k][1]-city[k][5];
        city[k][8]=city[k][4]+city[k][2]-city[k][6];
    }else if(l23>l12&&l23>l13){
        city[k][7]=city[k][3]+city[k][5]-city[k][1];
        city[k][8]=city[k][4]+city[k][6]-city[k][2];
    }else{
        city[k][7]=city[k][1]+city[k][5]-city[k][3];
        city[k][8]=city[k][2]+city[k][6]-city[k][4];
    }
}
inline lf spfa(int ss){
    GO(1,4*s,i)dis[i]=1e18;
    GO(1,4*s,i)inq[i]=false;
    inq[ss]=true;
    dis[ss]=0;
    q.push(ss);
    while(!q.empty()){
        int u=q.front();q.pop();inq[u]=false;
        GOGRA(e,head,u,i){
            int v=e[i].to;
            lf w=e[i].w;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                if(!inq[v])q.push(v);
                inq[v]=true;
            }
        }
    }
    lf ans=1e18;
    GO(1,4,i){
        ans=min(ans,dis[4*(b-1)+i]);
    }
    return ans;
}
inline void Read(){
    s=fr(),t=fr(),a=fr(),b=fr();
    GO(1,s,i){
        city[i][1]=fr();city[i][2]=fr();
        city[i][3]=fr();city[i][4]=fr();
        city[i][5]=fr();city[i][6]=fr();
        location(i);
        city[i][9]=fr();
        GO(1,4,ss)GO(1,4,tt){
            insert(4*(i-1)+ss,4*(i-1)+tt,city[i][9]*calc(city[i][2*ss-1],city[i][2*ss],city[i][2*tt-1],city[i][2*tt]));
        }
    }
    GO(1,s,uci)GO(1,4,up){
        GO(1,s,vci)GO(1,4,vp){
            insert(4*(uci-1)+up,4*(vci-1)+vp,calc(city[uci][up*2-1],city[uci][up*2],city[vci][vp*2-1],city[vci][vp*2])*t);
        }
    }
    return;
}
inline void Solve(){
    lf ans=1e18;
    GO(1,4,i){
        ans=min(ans,spfa((a-1)*4+i));
    }
    printf("%.1lf\n",ans);
    return;
}

inline void init(){
    len=0;GO(1,4*s,i)head[i]=0;
    GO(1,s,i)GO(1,9,j)city[i][j]=0;
    s=a=b=t=0;
    
}
signed main(){
    // freopen("Chorse.in","r",stdin);
    // freopen("Chores.out","w",stdout);
    int T=fr();
    GO(1,T,i){
        init();
        Read();
        Solve();
    }
    // fclose(stdin);
    // fclose(stdout);
    return 0;
}

模板有点长,请见谅

posted @ 2022-05-18 21:38  Locked_Fog  阅读(86)  评论(0)    收藏  举报