分别给出两条直线断点和每条直线上的代价、直线之外的代价 求最少的路线的花费
需要先确定一条直线上的点 则对于另外一条直线上的动点来说 花费就是一凸性函数了
所以先对第一条直线上得点进行三分 然后三分第二条直线上的点
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define eps 1e-7
#define mi 1e-9
struct point{
double x,y;
}a,b,c,d,aa,dd;
double ab,cd,p,q,r;
double dist(point &a,point &b){
return sqrt(eps+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double solve(double t)
{
dd.x=d.x+(c.x-d.x)/cd*t*q;
dd.y=d.y+(c.y-d.y)/cd*t*q;
return t+dist(aa,dd)/r;
}
double sf(double t){
aa.x=a.x+(b.x-a.x)/ab*t*p;
aa.y=a.y+(b.y-a.y)/ab*t*p;
double low=0,high=cd/q,mid,mmid;
while(high-low>eps)
{
mid=(low+high)/2;
mmid=(mid+high)/2;
if(solve(mid)<solve(mmid))high=mmid+mi;
else low=mid-mi;
}
return t+solve(mid);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
scanf("%lf%lf%lf",&p,&q,&r);
ab=dist(a,b),cd=dist(c,d);
double low=0,high=ab/p,mid,mmid;//三分ab
while(high-low>eps)
{
mid=(low+high)/2;
mmid=(mid+high)/2;
if(sf(mid)<sf(mmid))high=mmid+mi;
else low=mid-mi;
}
printf("%.2f\n",sf(mid));
}
return 0;
}