题目链接:无线通讯网 - 洛谷
题目大意是在最小生成树上求min(p-1,s+1)的边
最小生成树板子题, 开边的时候需要注意p<=500, 边数组要开(500+1)*500/2也就是125250, 不然可能会re
ac代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <stack>
#include <deque>
#include <map>
#include <set>
using namespace std;
#define ll long long
#define endl "\n"
#define rep(i, a, b) for (ll i = (a); i <= (b); i++)
#define repr(i, a, b) for (ll i = (a); i < (b); i++)
#define rrep(i, a, b) for (ll i = (b); i >= (a); i--)
#define rrepr(i, a, b) for (ll i = (b); i > (a); i--)
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
ll cnt,n,m,t,ant;
const int N=2e5+10;
ll arr[N];
ll x[N],y[N];
double ans[N];
string str;
inline ll read()
{
char c = getchar();int x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}//是符号
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}//是数字
return x*s;
}
ll find(ll x)
{
if(x!=arr[x]) arr[x]=find(arr[x]);
return arr[x];
}
double dis(ll a,ll b)
{
return sqrt(pow(x[a]-x[b],2)+pow(y[a]-y[b],2));
}
struct Edge
{
ll a,b;
double w;
bool operator<(const Edge &W)const
{
return w<W.w;
}
}edge[N];
void kruskal()
{
sort(edge,edge+cnt);
// repr(i,0,cnt) cout<<edge[i].a<<" "<<edge[i].b<<" "<<edge[i].w<<endl;
repr(i,0,cnt)
{
ll a=edge[i].a;
ll b=edge[i].b;
double w=edge[i].w;
a=find(a);
b=find(b);
if(a!=b)
{
arr[a]=b;
// cout<<a<<" "<<b<<" "<<w<<" "<<endl;
ans[ant++]=w;
}
if(ant>=n-1) return;
}
}
void solve()
{
m=read();
n=read();//点数
rep(i,0,n) arr[i]=i;
rep(i,1,n)
{
x[i]=read();
y[i]=read();
}
cnt=0;
rep(i,1,n)
rep(j,i+1,n)
edge[cnt++]={i,j,dis(i,j)};
kruskal();
printf("%.2lf",ans[ant-m]);
return;
}
int main()
{
solve();
return 0;
}