题意: 给定长度为N的海滩,然后有M做防御塔,给出每座塔的位置Xi,到海岸的距离Yi。 求防御塔上最小观测半径Ri,使得海滩被封锁。

思路:要使左边界和右边界连通。

很nice,可以二分+并查集做。 可以最小生成树做。 可以最短路做。

MST代码:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
double x[maxn],y[maxn],ans; int tot,fa[maxn];
struct in{
    int u,v;
    double len;
}s[maxn];
bool cmp(in w,in p){return w.len<p.len;}
void add(int u,int v,double len)
{
    tot++; s[tot].u=u; s[tot].v=v; s[tot].len=len;
}
int find(int x){
    if(x==fa[x]) return x;
    return fa[x]=find(fa[x]);
}
int main()
{
    int N,M;
    scanf("%d%d",&N,&M);
    rep(i,1,M) scanf("%lf%lf",&x[i],&y[i]);
    rep(i,0,N+1) fa[i]=i;
    rep(i,1,M) add(0,i,x[i]),add(N+1,i,N-x[i]);
    rep(i,1,M) rep(j,1,M) add(i,j,0.5*sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
    sort(s+1,s+tot+1,cmp);
    rep(i,1,tot){
        int fu=find(s[i].u);
        int fv=find(s[i].v);
        if(fu==fv) continue;
        fa[fu]=fv;
        ans=s[i].len;
        if(find(0)==find(N+1)) break;
    }
    printf("%.2lf\n",ans);
    return 0;
}
View Code

相关文章:

  • 2022-02-19
  • 2021-06-03
  • 2021-06-23
  • 2021-08-28
  • 2022-12-23
  • 2022-01-01
  • 2021-10-27
  • 2022-03-06
猜你喜欢
  • 2021-06-09
  • 2021-09-23
  • 2022-01-24
  • 2021-08-12
  • 2021-09-15
  • 2021-05-31
  • 2021-07-27
相关资源
相似解决方案