Arctic Network POJ - 2349 Kruskal
阿新 • • 發佈:2019-01-13
題解
根據題意 需要將所有點聯通 但是有M個衛星通訊裝置 所以可以省去M-1條邊
先使用Kruskal跑最小生成樹 再減去M-1條較大邊剩下的取最大為答案
AC程式碼
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-6;
const int MAXN = 5e2 + 10;
int M, N;
int vex[MAXN];
struct node
{
int x, y;
}a[MAXN];
struct edge
{
int u, v;
double w;
edge(int a, int b, double c) : u(a), v(b), w(c){}
bool operator < (const edge &oth) const
{
return w < oth.w;
}
};
vector<edge> ed;
double dis (int x1, int y1, int x2, int y2)
{
return sqrt((x1 - x2) * (x1 - x2) * 1.0 + (y1 - y2) * (y1 - y2) * 1.0);
}
int findr(int x)
{
return vex[x] == x ? x : vex[x] = findr(vex[x]);
}
void join(int x, int y)
{
int yy = findr(y);
int xx = findr(x);
vex[yy] = xx;
}
double kru()
{
for (int i = 0; i < N; i++)
vex[i] = i;
vector<double> vec;
for (int i = 0; i < ed.size(); i++)
if (findr(ed[i].u) != findr(ed[i].v))
{
join(ed[i].u, ed[i].v);
vec.push_back(ed[i].w);
}
double ans = 0;
for (int i = 0; i < vec.size() - M + 1; i++) //減去M-1條較長邊
ans = max(ans, vec[i]);
return ans;
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
cin >> M >> N;
for (int i = 0; i < N; i++)
scanf("%d%d", &a[i].x, &a[i].y);
ed.clear();
for (int i = 0; i < N; i++)
for (int j = i + 1; j < N; j++)
ed.push_back(edge(i, j, dis(a[i].x, a[i].y, a[j].x, a[j].y)));
sort(ed.begin(), ed.end());
printf("%.2lf\n", kru());
}
return 0;
}