牛客国庆集训派对Day1-L New Game!

版权声明:本文为博主原创文章,未经博主允许不得转载。 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];
	}
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/82975737