https://www.nowcoder.com/acm/contest/201/L
题意:给两条平行的直线,还有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;
}