傳送門
解題思路
和上一道題基本相同。
但是這個題題面是真的複雜,讀了好久纔讀懂。
關鍵在於如何建圖。
將在第0列可以看做第0個點,第n列可以看做第m+1個點。
這兩個特殊的點到其他點的距離爲點線垂直距離,其他的點之間的距離爲點點距。
還有不同的地方就是兩個信號塔之間的距離是兩個半徑,而0點和m+1點到其他點的距離一個半徑,建圖時將其中一個除以2或者另一個乘2即可。
AC代碼
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
const int maxn=1005;
int n,m,fa[maxn],cnt;
double ans;
struct node{
int u,v;
double w;
}e[maxn*maxn];
struct Node{
double x,y;
}a[maxn];
bool cmp(node a,node b){
return a.w<b.w;
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
double getdis(int i,int j){
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))/2;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=0;i<=m+1;i++) fa[i]=i;
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].y;
}
for(int i=1;i<=m;i++) {
e[++cnt].u=0;
e[cnt].v=i;
e[cnt].w=a[i].x;
e[++cnt].u=i;
e[cnt].v=m+1;
e[cnt].w=(n-a[i].x);
}
for(int i=1;i<m;i++){
for(int j=i+1;j<=m;j++){
e[++cnt].u=i;
e[cnt].v=j;
e[cnt].w=getdis(i,j);
}
}
sort(e+1,e+cnt+1,cmp);
for(int i=1;i<=cnt;i++){
ans=e[i].w;
int x=find(e[i].u),y=find(e[i].v);
if(x!=y){
fa[x]=y;
}
if(find(0)==find(m+1)) break;
}
cout<<fixed<<setprecision(2)<<ans;
return 0;
}