1. 程式人生 > >Arctic Network POJ - 2349 Kruskal

Arctic Network POJ - 2349 Kruskal

題解

根據題意 需要將所有點聯通 但是有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; }