版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/82975737
地址:https://www.nowcoder.com/acm/contest/201/L
思路:可以将线段和圆转换成图来处理,对于不同圆间的距离则为圆心间距离-两圆半径,而线段和圆间距离则为圆心到线段的距离-半径,而线段与线段间的距离则为一线段上一点到另一线段的距离,这样就转换成起点线段S到终点线段T的最短距离了,可以用Dijkstra来求解
Code :
#include<iostream>
#include<cmath>
using namespace std;
struct node{
int x;
int y;
int r;
};
const int MAX_N=10005;
int n;
node d[MAX_N];
double G[MAX_N][MAX_N];
double dis[MAX_N];
bool boo[MAX_N];
void Dijkstra(int S);
int main()
{
ios::sync_with_stdio(false);
int a,b,c1,c2;
while(cin>>n>>a>>b>>c1>>c2){
G[0][0]=G[n+1][n+1]=0;
double xi=0,yi=0;
if(!a){
yi=-c2/b;
}else xi=-c2/a;
G[0][n+1]=G[n+1][0]=max(0.0,abs((a*xi+b*yi+c1)/sqrt(a*a+b*b)));
for(int i=1;i<=n;++i)
{
cin>>d[i].x>>d[i].y>>d[i].r;
G[0][i]=G[i][0]=max(0.0,abs((a*d[i].x+b*d[i].y+c1)/sqrt(a*a+b*b))-d[i].r);
G[n+1][i]=G[i][n+1]=max(0.0,abs((a*d[i].x+b*d[i].y+c2)/sqrt(a*a+b*b))-d[i].r);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
G[i][j]=max(0.0,sqrt(pow(d[i].x-d[j].x,2)+pow(d[i].y-d[j].y,2))-d[i].r-d[j].r);
Dijkstra(0);
cout<<dis[n+1]<<endl;
}
return 0;
}
void Dijkstra(int S)
{
for(int i=0;i<=n+1;++i)
dis[i]=G[S][i];
dis[S]=0; boo[S]=true;
for(int i=0;i<=n;++i)
{
int u=0;
double Min=1e9;
for(int j=0;j<=n+1;++j)
if(boo[j]==false&&Min>dis[j]){
Min=dis[j]; u=j;
}
boo[u]=true;
for(int j=0;j<=n+1;++j)
if(dis[j]>dis[u]+G[u][j])
dis[j]=dis[u]+G[u][j];
}
}