洛谷 P1783 海灘防禦 做題記錄

coding_goat_qwq發表於2024-10-21

至少多大的半徑,想到二分長度,則判斷方式為第 \(0\) 列和第 \(m\) 列是否存在一條路徑。我們將一個基站和它可到達的基站放在一個連通塊裡面,提前將可以連到第 \(0\) 列和第 \(n\) 列的基站加入連通塊,則如果它們最終在一個連通塊內,答案可行。

點選檢視程式碼
#include<bits/stdc++.h>

#define mem(aqwqawa,bqwqawa) memset((aqwqawa),(bqwqawa),sizeof(aqwqawa))
#define m0(aqwqawa) memset((aqwqawa),0,sizeof(aqwqawa))
#define lb(xqwqawa) ((xqwqawa)&-(xqwqawa))
#define lc(xqwqawa) ((xqwqawa)<<1)
#define rc(xqwqawa) (((xqwqawa)<<1)|1)
#define pb(Gqwqawa,xqwqawa) (Gqwqawa).push_back((xqwqawa))
#define For(Aqwqawa,Bqwqawa,Cqwqawa) for(int Aqwqawa=(Bqwqawa);Aqwqawa<=(Cqwqawa);Aqwqawa++)
#define Rep(Aqwqawa,Bqwqawa,Cqwqawa) for(int Aqwqawa=(Bqwqawa);Aqwqawa>=(Cqwqawa);Aqwqawa--)
#define in1(Aqwqawa) Aqwqawa=read()
#define in2(Aqwqawa,Bqwqawa) Aqwqawa=read(), Bqwqawa=read()
#define in3(Aqwqawa,Bqwqawa,Cqwqawa) Aqwqawa=read(), Bqwqawa=read(), Cqwqawa=read()
#define inn(Aqwqawa,Nqwqawa) For(Iqwqawa,1,Nqwqawa) Aqwqawa[Iqwqawa]=read();

#define ll long long
using namespace std;
inline int read() {
	int xx= 0;int f= 1;
	char c = getchar();
	while(c<'0'||c>'9') { 
		if(c=='-') f= -1;
		c= getchar();
	}
	while(c>='0'&&c<='9') {
		xx= (xx<<1)+(xx<<3)+(c^48);
		c= getchar();
	}
	return xx*f;
}
#define maxn 850
int n,m;
double x[maxn],y[maxn];
int fa[maxn];
int find(int x) {return x==fa[x]?fa[x]:fa[x]=find(fa[x]); }
double len(double a,double b,double c,double d) {
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
bool check(double dis) {
	For(i,0,m+1) fa[i]=i;
	For(i,1,m) if(x[i]<=dis) fa[find(i)]=find(0);
	For(i,1,m) if(n-x[i]<=dis) fa[find(i)]=find(m+1);
	For(i,1,m) For(j,1,m) {
		if(i!=j&&find(i)!=find(j)&&len(x[i],y[i],x[j],y[j])<=(dis+dis)) {
			fa[find(i)]=find(j);
		}
	}
	return find(0)==find(m+1);
}
signed main() {
	scanf("%d%d",&n,&m);
	For(i,1,m) {
		scanf("%lf%lf",&x[i],&y[i]);
	}
//	cout<<check(1);
	double l=0,r=100000;
	while(r-l>0.0001) {
		double mid=(l+r)/2.0;
		if(check(mid)) r=mid;
		else l=mid;
	}
	printf("%.2lf",r);
}