#UVa:10369-Arctic Network

灆洢 2020-04-27 01:51:25

利用兩點之間距離,透過 Kruskal 演算法建立起一棵連結所有節點的最小生成樹。接著將樹中最長的 S 條邊利用 Satellite Channels 取代掉,最後剩下來最長的邊的長度就是答案。

C++(0.030)

/*******************************************************/
/* UVa 10369 Arctic Network                            */
/* Author: Maplewing [at] knightzone.studio            */
/* Version: 2020/04/27                                 */
/*******************************************************/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

struct Point {
  double x;
  double y;

  double getLength(const Point& point) {
    double diffX = x - point.x;
    double diffY = y - point.y;
    return sqrt(diffX * diffX + diffY * diffY);
  }
};

struct Outpost {
  Point position;
  int setNumber;
};

int findRoot(vector<Outpost>& outposts, int setNumber) {
  if (outposts[setNumber].setNumber == setNumber) return setNumber;
  return outposts[setNumber].setNumber = 
    findRoot(outposts, outposts[setNumber].setNumber);
}

bool unionSet(vector<Outpost>& outposts, int aIndex, int bIndex) {
  int aRoot = findRoot(outposts, aIndex);
  int bRoot = findRoot(outposts, bIndex);

  if (aRoot == bRoot) return false;

  outposts[bRoot].setNumber = aRoot;
  return true;
}

struct Edge {
  int aIndex;
  int bIndex;
  double length;
};

bool edgeCompare(const Edge& a, const Edge& b) {
  return a.length < b.length;
}

int main() {
  int caseAmount;
  while (scanf("%d", &caseAmount) != EOF) {
    for (int caseNumber = 1 ; caseNumber <= caseAmount ; ++caseNumber) {
      int S, P;
      scanf("%d%d", &S, &P);

      vector<Outpost> outposts(P);
      for (int i = 0 ; i < P ; ++i) {
        scanf("%lf%lf", &(outposts[i].position.x), &(outposts[i].position.y));
        outposts[i].setNumber = i;
      }

      vector<Edge> edges;
      for (int i = 0 ; i < P ; ++i) {
        for (int j = i + 1 ; j < P ; ++j) {
          edges.push_back((Edge) { i, j, 
            outposts[i].position.getLength(outposts[j].position) });
        }
      }
      sort(edges.begin(), edges.end(), edgeCompare);

      vector<Edge> mspEdges;
      for (int i = 0 ; mspEdges.size() < P - 1; ++i) {
        if (!unionSet(outposts, edges[i].aIndex, edges[i].bIndex)) {
          continue;
        }

        mspEdges.push_back(edges[i]);
      }

      printf("%.2lf\n", mspEdges[P - 1 - S].length);
    }
  }
  return 0;
}

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料