[luogu] P2498 [SDOI2012]拯救小云公主 二分答案+bfs

前言

以为二分的是人到BOOS的距离
没想到可以直接二分BOOS的攻击距离
传送门 :

思路

BFS待研究

CODE

typedef pair<int,int> pii;
map<int,int> mp;

int cal(int x1,int y1,int x2,int y2){
	return pow(x1-x2,2)+ pow(y1-y2,2);
}

bool check(int d,double r){
	return r * r * 4 >d;
}

const int N  =  3e3+10;
const double eps = 1e-5;
int n,line,row;
int x[N],y[N];
int dist[N][N];
int st[N];
queue<int> q;


bool bfs(double r){
	memset(st,0,sizeof st);
	while(!q.empty()) q.pop();

	for(int i=1;i<=n;i++)
		if(x[i]<r || row - y[i] < r)
		q.push(i),st[i] = 1;

	while(!q.empty())
	{
		int p = q.front();
		q.pop();
		if(line - x[p] < r || y[p] < r) return false;
		for(int i=1;i<=n;i++)
			if(!st[i] && check(dist[p][i],r))
			st[i] = 1,q.push(i);
	}
	return true;


}

void solve()
{
	cin>>n>>line>>row;
	line -- ,row -- ;
	for(int  i = 1;i<=n;i++){
		cin>>x[i]>>y[i];x[i]--,y[i] -- ;
	}

	for(int i=1;i<=n;i++)
		for(int j=1;j<i;j++)
			{
				dist[i][j] = dist[j][i] =
				cal(x[i],y[i],x[j],y[j]);
			}

		double l = 0 ,r = min(row,line);
		while(r - l > eps){
			double mid  =  (l+r)/2;
			if(bfs(mid)) l = mid;
			else r = mid;
		}
		printf("%.2lf",l);
}

你可能感兴趣的:(#,Luogu,宽度优先,图论,算法)