注意到我们可以转换成图求最小生成树,但是边数太多,用Kruskal只能80分,必须用Prim。
但是完全不会写Prim,改悔!
还是要多注意不同算法的效率差异。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e5+5;
const ll Inf=1e18;
ll x[N],y[N];
ll n,m,k,ans,dis[N],vis[N];
ll cnt,to[N],edge[N],from[N],nxt[N],head[N];
void ins(ll x,ll y,ll z) {
to[++cnt]=y;nxt[cnt]=head[x];edge[cnt]=z;head[x]=cnt;
}
ll calc(ll a,ll b) {
if (a>k||b>k) return (y[a]-y[b])*(y[a]-y[b]);
else return (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]);
}
void prim() {
for(ll i=1;i<=k+2;i++) dis[i]=Inf;dis[k+1]=0;
for(ll i=1;i<=k+2;i++) {
ll x=0,mn=Inf;
for(ll j=1;j<=k+2;j++) if(!vis[j]&&dis[j]<mn) mn=dis[j],x=j;
vis[x]=1;
if(from[x]) ins(x,from[x],dis[x]),ins(from[x],x,dis[x]);
for(ll j=1;j<=k+2;j++) if(!vis[j]&&calc(x,j)<dis[j]) dis[j]=calc(x,j),from[j]=x;
}
}
void dfs(ll x,ll fa,ll mx) {
if(x==k+2) ans=mx;
for(ll i=head[x];i;i=nxt[i]) {
ll y=to[i],z=edge[i];
if(y!=fa) dfs(y,x,max(mx,z));
}
}
int main() {
scanf("%d%d%d",&n,&m,&k);
for(ll i=1;i<=k;i++) scanf("%d%d",&x[i],&y[i]);
y[k+1]=0,y[k+2]=m;
prim();
dfs(k+1,0,0);
printf("%.8lf\n",sqrt(ans)/2.0);
return 0;
}