1. 程式人生 > >最短路——洛谷P1027 Car的旅行路線

最短路——洛谷P1027 Car的旅行路線

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); } }