最短路——洛谷P1027 Car的旅行路線
阿新 • • 發佈:2019-01-26
https://www.luogu.org/problem/show?pid=1027
預處理完就floyd就好了;
首先是三個點求第四個點;
因為三個點會形成一個直角三角形;
找到最長的邊,就是斜邊;
斜邊取中點,然後把那個直角的點對稱過去就好了;
然後算距離嘛
隨後AB的機場4*4比較一下就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define y1 fuck
#define Ll long long
using namespace std;
struct cs{int x,y,vv,num;}a[405];
struct D{double v;int x,y;};
double f[405][405];
int m,n,v,S,E,x1,x2,x3,y1,y2,y3,vv,ll;
void make(int k,int x1,int y1,int x2,int y2,int x3,int y3){
int x[5],y[5];
x[1]=x1;y[1]=y1;
x[2]=x2;y[2]=y2;
x[3]=x3;y[3]=y3;
D A,B,C,ans;
A.x=1;A.y=2 ;A.v=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
B.x=1;B.y=3;B.v=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
C.x=3;C.y=2;C.v=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
if(A.v>B.v)ans=A;else ans=B;
if(C.v>ans.v)ans=C;
double xx=double(x[ans.x]+x[ans.y])/2,yy=double(y[ans.x]+y[ans.y])/2;
int o=6-ans.x-ans.y;
a[k].x=xx+(xx-x[o]);
a[k].y=yy+(yy-y[o]);
}
int main()
{
scanf("%d",&m);
while(m--){
ll=0;
scanf("%d%d%d%d",&n,&v,&S,&E);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&vv);
a[++ll].num=i; a[ll].vv=vv;
a[ll].x=x1;a[ll].y=y1;
a[++ll].num=i; a[ll].vv=vv;
a[ll].x=x2;a[ll].y=y2;
a[++ll].num=i; a[ll].vv=vv;
a[ll].x=x3;a[ll].y=y3;
a[++ll].num=i; a[ll].vv=vv;
make(ll,x1,y1,x2,y2,x3,y3);
}
for(int i=1;i<=ll;i++)
for(int j=1;j<=ll;j++){
double l=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
if(a[i].num==a[j].num)f[i][j]=l*a[i].vv;
else f[i][j]=l*v;
}
for(int k=1;k<=ll;k++)
for(int i=1;i<=ll;i++)
for(int j=1;j<=ll;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
x1=(S-1)*4+1; x2=(E-1)*4+1;
double ans=1e9;
for(int i=x1;i<=x1+3;i++)
for(int j=x2;j<=x2+3;j++)
ans=min(ans,f[i][j]);
printf("%.1lf\n",ans);
}
}