思路:先算出从回收站T出发回收各瓶子的距离
#include<bits/stdc++.h>
#define N 110000
using namespace std;
typedef long long ll;
const double eps=1e-8;
int sgn(double x)
{
if(fabs(x)<=eps)
return 0;
else
return x>0?1:-1;
}
struct node
{
double x,y;
double disa,disb,dist;
bool operator !=(const node &temp)
{
return (x!=temp.x)||(y!=temp.y);
}
};
bool cmpa(node a,node b)
{
return a.disa-a.dist<b.disa-b.dist;
}
bool cmpb(node a,node b)
{
return a.disb-a.dist<b.disb-b.dist;
}
double dis(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double ax,ay,bx,by,tx,ty,ans;
int n,i;
node q[N];
node f1,f2,f3,f4;
int main()
{
while(~scanf("%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&tx,&ty))
{
scanf("%d",&n);
ans=0.0;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&q[i].x,&q[i].y);
q[i].disa=dis(q[i].x,q[i].y,ax,ay);
q[i].disb=dis(q[i].x,q[i].y,bx,by);
q[i].dist=dis(q[i].x,q[i].y,tx,ty);
ans+=2.0*q[i].dist;//先算出从回收站T出发回收各瓶子的距离
}
sort(q+1,q+n+1,cmpa);//按到A与到T距离之差排序
f1=q[1];f2=q[2];//记录最小的两个点
sort(q+1,q+n+1,cmpb);//按到B与到T距离之差排序
f3=q[1];f4=q[2];
if(f1!=f3)//如果两次排序最小的点不是同一个
{
if(sgn(f1.disa-f1.dist)>0&&sgn(f3.disb-f3.dist)>0)
ans+=min(f1.disa-f1.dist,f3.disb-f3.dist);
else if(sgn(f1.disa-f1.dist)>0&&sgn(f3.disb-f3.dist)<=0)//不需要A去捡
ans+=f3.disb-f3.dist;
else if(sgn(f1.disa-f1.dist)<=0&&sgn(f3.disb-f3.dist)>0)//不需要B去捡
ans+=f1.disa-f1.dist;
else
ans+=f1.disa-f1.dist+f3.disb-f3.dist;
}
else//如果两次排序最小的点是同一个
{
if(sgn(f1.disa-f1.dist)>0&&sgn(f3.disb-f3.dist)>0)
ans+=min(f1.disa-f1.dist,f3.disb-f3.dist);
else if(sgn(f1.disa-f1.dist)>0&&sgn(f3.disb-f3.dist)<=0)//不需要A去捡
ans+=f3.disb-f3.dist;
else if(sgn(f1.disa-f1.dist)<=0&&sgn(f3.disb-f3.dist)>0)//不需要B去捡
ans+=f1.disa-f1.dist;
else
{
if(sgn(f2.disa-f2.dist)>0)
f2.disa=f2.dist;
if(sgn(f4.disb-f4.dist)>0)
f4.disb=f4.dist;
ans+=min(f1.disa-f1.dist+f4.disb-f4.dist,f2.disa-f2.dist+f3.disb-f3.dist);
}
}
printf("%.12lf\n",ans);
}
return 0;
}