# 【luogu P1783 海滩防御】 题解

——类似kruskal的算法实现。

code：

#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
struct edge{
int u, v;
double w;
}e[1000010];
bool cmp(edge x, edge y)
{
return x.w < y.w;
}
int n, m, cnt, fa[maxn];
int dx[maxn], dy[maxn];
double distance(int x1, int y1, int x2, int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void init()
{
for(int i = 0; i <= m+1; i++) fa[i] = i;

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 = distance(dx[i], dy[i], dx[j], dy[j])/2;
for(int i = 1; i <= m; i++)
e[++cnt].u = i, e[cnt].v = 0, e[cnt].w = dx[i];
for(int i = 1; i <= m; i++)
e[++cnt].u = i, e[cnt].v = m+1, e[cnt].w = n - dx[i];
}
int find(int x)
{
if(fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
double kruskal()
{
double ans = -1000.0;
sort(e+1, e+cnt+1, cmp);
for(int i = 1; i <= cnt; i++)
{
int fu = find(e[i].u); int fv = find(e[i].v);
if(fu != fv)
{
fa[fu] = fv;
ans = max(ans, e[i].w);
}
int f0 = find(0); int fm = find(m+1);
if(f0 == fm) break;
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
int L = n+2, R = -1;
for(int i = 1; i <= m; i++)
scanf("%d%d",&dx[i],&dy[i]);
init();
printf("%0.2f",kruskal());
return 0;
}

posted @ 2019-06-10 19:07  Misaka_Azusa  阅读(128)  评论(0编辑  收藏
Live2D