Car的旅行路线 题解 P1027
题解 Car的旅行路线
题目大意
懒得抄了,太长了,直接放链接吧
分析
其实就是写了半天的最短路
我们需要几个东西
首先,要计算每个城市的第四个点
这个要应用一下我们贫乏的初中数学知识
\[设矩形四个顶点的坐标分别为\\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;
}
模板有点长,请见谅

浙公网安备 33010602011771号