题意思路:
https://www.cnblogs.com/yueshuqiao/archive/2011/08/24/2152471.html
Kruskal:
参考大佬的代码:
#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 505;
struct point
{
double x, y;
};
point a[maxn];//读入点
struct EDGE
{
int u, v;
double w;
};
bool cmp(EDGE a, EDGE b)
{
return a.w < b.w;
}
EDGE edge[maxn * maxn];//计算之后用于存储边
int n;
int s, p;
int par[maxn];
double ans[maxn * maxn];
int cnt = 0;//数组下标计数
int find(int x)
{
if (par[x] == x)
return par[x];
return par[x] = find(par[x]);
}
void initialize()
{
cnt = 0;
for (int i = 0; i < p; i++)
par[i] = i;
}
double cal_dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main()
{
cin >> n;
while (n--)
{
cin >> s >> p;
initialize();
for (int i = 0; i < p; i++)
cin >> a[i].x >> a[i].y;
for (int i = 0; i < p; i++)
for (int j = 0; j < p; j++)
{
edge[cnt].u = i;
edge[cnt].v = j;
edge[cnt].w = cal_dis(a[i].x, a[i].y, a[j].x, a[j].y);
cnt++;
}
sort(edge, edge + cnt, cmp);
int t = p;
int cnt2 = 0;
//int t = 0;
for (int i = 0; i < cnt; i++)
{
int fa = find(edge[i].u);
int fb = find(edge[i].v);
if (fa != fb)
{
par[fb] = fa;
ans[cnt2++] = edge[i].w;
t--;
if (t == 1)
break;
/*ans[t++] = edge[i].w;
if (t == p - 1)
break;*/
}
}
//sort(ans, ans + t);
printf("%.2lf\n", ans[p - s - 1]);
/*for (int i = 0; i <= cnt2; i++)
cout << ans[i] << " ";*/
/*for (int i = 0; i <= t; i++)
cout << ans[i] << " ";*/
}
return 0;
}
#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 505;
struct point
{
double x, y;
};
point a[maxn];//读入点
struct EDGE
{
int u, v;
double w;
};
bool cmp(EDGE a, EDGE b)
{
return a.w < b.w;
}
EDGE edge[maxn * maxn];//计算之后用于存储边
int n;
int s, p;
int par[maxn];
double ans[maxn * maxn];
int cnt = 0;//数组下标计数
int find(int x)
{
if (par[x] == x)
return par[x];
return par[x] = find(par[x]);
}
void initialize()
{
cnt = 0;
for (int i = 0; i < p; i++)
par[i] = i;
}
double cal_dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main()
{
cin >> n;
while (n--)
{
cin >> s >> p;
initialize();
for (int i = 0; i < p; i++)
cin >> a[i].x >> a[i].y;
for (int i = 0; i < p; i++)
for (int j = 0; j < p; j++)
{
edge[cnt].u = i;
edge[cnt].v = j;
edge[cnt].w = cal_dis(a[i].x, a[i].y, a[j].x, a[j].y);
cnt++;
}
sort(edge, edge + cnt, cmp);
/*int t = p;
int cnt2 = 0;*/
int t = 0;
for (int i = 0; i < cnt; i++)
{
int fa = find(edge[i].u);
int fb = find(edge[i].v);
if (fa != fb)
{
par[fb] = fa;
/*ans[cnt2++] = edge[i].w;
t--;
if (t == 1)
break;*/
ans[t++] = edge[i].w;
if (t == p - 1)
break;
}
}
sort(ans, ans + t);
printf("%.2lf\n", ans[p - s - 1]);
/*for (int i = 0; i <= t; i++)
cout << ans[i] << " ";*/
}
return 0;
}