P2498 [SDOI2012]拯救小云公主
阿新 • • 發佈:2021-08-13
考慮二分答案。
如何 check ?明顯不能進入的區域是以怪物為圓心,mid為半徑的圓。兩個圓是否聯通就看\(dis(i,j)\)是否大於\(2\times mid\)。然後並查集判斷是否能有縫隙通過即可。
容易發現與上下、左右邊界聯通時不能找到縫隙。
#include<bits/stdc++.h> using namespace std; int n,row,line; int fa[3005]; double mx[3005],my[3005]; int f(int x){ return x==fa[x]?x:fa[x]=f(fa[x]); } double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } bool check(double w){ for(int i=0;i<=n+1;i++)fa[i]=i; for(int i=1;i<n;i++){ for(int j=i;j<=n;j++){ if(dis(mx[i],my[i],mx[j],my[j])<=2*w)fa[f(i)]=f(j); } } for(int i=1;i<=n;i++){ if(mx[i]-w<=1||my[i]+w>=line)fa[f(i)]=f(0); if(mx[i]+w>=row||my[i]-w<=1)fa[f(i)]=f(n+1); } return f(0)!=f(n+1); } int main(){ cin>>n>>row>>line; for(int i=1;i<=n;i++)cin>>mx[i]>>my[i]; double l=0,r=114514; while(r-l>1e-5){ double mid=(l+r)/2; if(check(mid))l=mid; else r=mid; } printf("%.2lf",l); return 0; }
會TLE。可以選擇把精度調到\(10^{-3}\),或者吸口老氧。
YJX AK IOI