New Game! (最短路)
阿新 • • 發佈:2018-12-13
題意:給兩條平行的直線,還有n個圓,在直線和圓上走不耗時間,求最短的時間從一條直線到另一條。
思路:這道題就是讓求最短距離,但真沒想到真是用最短路寫的。。。
程式碼中0,1位置存的是兩條直線節點,
#include<bits/stdc++.h> using namespace std; #define N 1000+10 int n; double a,b,c1,c2; struct nomd { int to; double cost; } ; double ww(double a,double b,double x,double y,double c) { return fabs((a*x+b*y+c)/sqrt(x*x+y*y)); } double www(double a,double b,double x,double y) { return fabs(sqrt((x-a)*(x-a)+(y-b)*(y-b))); } vector<nomd> G[N]; double s[N],ss[N]; double d[N]; double oo[N],pp[N],ii[N]; typedef pair<int ,int >P; void di(int q) { priority_queue<P,vector<P>,greater<P> > que; for(int i=0;i<=n+2;i++) d[i]=1000000000; d[q]=0; que.push(P(0,q)); while(!que.empty()) { P p=que.top();que.pop(); int v=p.second; if(d[v]<p.first) continue; for(int i=0;i<G[v].size();i++) { nomd e=G[v][i]; if(d[e.to]>d[v]+e.cost) { d[e.to]=d[v]+e.cost; que.push(P(d[e.to],e.to)); } } } } int main() { cin>>n>>a>>b>>c1>>c2; for(int i=2;i<n+2;i++) { cin>>ii[i]>>oo[i]>>pp[i]; if(ww(ii[i],oo[i],a,b,c1)<=pp[i]) { s[i]=1; } if(ww(ii[i],oo[i],a,b,c2)<=pp[i]) { ss[i]=1; } for(int j=2;j<i;j++) { nomd e; e.to=i; if(s[i]==s[j]&&s[i]==1||ss[i]==ss[j]&&ss[i]==1||www(ii[i],oo[i],ii[j],oo[j])<=pp[i]+pp[j]) e.cost=0; else e.cost=www(ii[i],oo[i],ii[j],oo[j])-pp[i]-pp[j]; G[j].push_back(e); e.to=j; G[i].push_back(e); } } for(int i=2;i<n+2;i++) { nomd e; e.to=i; if(s[i]==1) { e.cost=0; } else { e.cost=ww(ii[i],oo[i],a,b,c1)-pp[i]; } G[0].push_back(e); e.to=0; G[i].push_back(e); } for(int i=2;i<n+2;i++) { nomd e; e.to=i; if(ss[i]==1) { e.cost=0; } else { e.cost=ww(ii[i],oo[i],a,b,c2)-pp[i]; } G[1].push_back(e); e.to=1; G[i].push_back(e); } nomd e; e.cost=fabs((c1-c2)/sqrt(a*a+b*b)); e.to=1; G[0].push_back(e); e.to=0; G[1].push_back(e); di(0); printf("%.6lf\n",d[1]); return 0; }