http://acm.split.hdu.edu.cn/showproblem.php?pid=3400
题意:
有两条带子ab和cd,在ab上的速度为p,在cd上的速度为q,在其它地方的速度为r。现在计算从a出发到达d的最少花费时间。
思路:
分别在ab和cd两段线路上找一个转折点,然后就是由这三段路组成。
设ab上的线路长度为x,cd上的为y,其余为z。
那么总的时间就是,分开来考虑,,F(x)是个单调递增函数,G(y,z)是个凹性函数。
那么总的T函数还是一个凹性函数,那么就可以三分了,对ab进行一次三分,然后继续对cd进行三分。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const int maxn = 300000+5; 16 17 const double eps=1e-8; 18 19 struct node 20 { 21 double x,y; 22 }a,b,c,d; 23 24 double p,q,r; 25 26 double getdis(node t1, node t2) 27 { 28 return sqrt((t2.y-t1.y)*(t2.y-t1.y)+(t2.x-t1.x)*(t2.x-t1.x)); 29 } 30 31 double solve_cd(node ab) 32 { 33 node mid, midd; 34 node t1=c,t2=d; 35 double d1,d2; 36 do 37 { 38 mid.x=(t1.x+t2.x)/2; 39 mid.y=(t1.y+t2.y)/2; 40 midd.x=(mid.x+t2.x)/2; 41 midd.y=(mid.y+t2.y)/2; 42 d1=getdis(mid,ab)/r+getdis(d,mid)/q; 43 d2=getdis(midd,ab)/r+getdis(d,midd)/q; 44 if(d1<d2) t2=midd; 45 else t1=mid; 46 }while(getdis(t1,t2)>=eps); 47 return min(d1,d2); 48 } 49 50 double solve_ab() 51 { 52 node mid, midd; 53 node t1=a,t2=b; 54 double ans1,ans2; 55 do 56 { 57 mid.x=(t1.x+t2.x)/2; 58 mid.y=(t1.y+t2.y)/2; 59 midd.x=(mid.x+t2.x)/2; 60 midd.y=(mid.y+t2.y)/2; 61 double d1=getdis(mid,a); 62 double d2=getdis(midd,a); 63 ans1=d1/p+solve_cd(mid); 64 ans2=d2/p+solve_cd(midd); 65 if(ans1<ans2) t2=midd; 66 else t1=mid; 67 }while(getdis(t1,t2)>=eps); 68 return min(ans1,ans2); 69 } 70 71 int main() 72 { 73 //freopen("in.txt","r",stdin); 74 int T; 75 scanf("%d",&T); 76 while(T--) 77 { 78 scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y); 79 scanf("%lf%lf%lf",&p,&q,&r); 80 printf("%.2f ",solve_ab()); 81 } 82 return 0; 83 }