1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| #include<bits/stdc++.h> #define dwb double
using namespace std;
const int AddRange = 15; const int SeeRange = 108;
const int MAXN = 100055; const dwb INF = 1e18;
struct Edge { int from, to; dwb weight; bool operator < (const Edge another) const { return weight < another.weight; } };
int n, m; int px[5], py[5]; dwb t1[MAXN], t2[MAXN]; dwb x1_, y1_, x2_, y2_;
int anc[MAXN << 1];
vector<Edge> edge;
inline void AncInit(int siz) { for (int i = 1; i <= siz; ++i) anc[i] = i; return; } inline int findAnc(int cur) { if (cur != anc[cur]) anc[cur] = findAnc(anc[cur]); return anc[cur]; } inline void merge(int a, int b) { anc[findAnc(a)] = findAnc(b); }
inline dwb calX(dwb t, int p1, int p2) { return px[p1] * t + px[p2] * (1 - t); } inline dwb calY(dwb t, int p1, int p2) { return py[p1] * t + py[p2] * (1 - t); } inline dwb calDis() { return sqrt((x1_ - x2_) * (x1_ - x2_) + (y1_ - y2_) * (y1_ - y2_)); }
inline void kruskal() { dwb mst = 0; sort(edge.begin(), edge.end()); AncInit(n + m); int edgeCount = 0, aim = n + m - 1; for (Edge e : edge) { int ancFrom = findAnc(e.from); int ancTo = findAnc(e.to); if (ancFrom != ancTo) { merge(ancFrom, ancTo); mst += e.weight; edgeCount++; if (edgeCount == aim) break; } } printf("%.3lf", mst); }
inline void init() { scanf("%d%d", &n, &m); for (int i = 1; i <= 4; ++i) scanf("%d%d", &px[i], &py[i]); for (int i = 1; i <= n; ++i) scanf("%lf", &t1[i]); for (int i = 1; i <= m; ++i) scanf("%lf", &t2[i]);
sort(t1 + 1, t1 + 1 + n); sort(t2 + 1, t2 + 1 + m);
for (int i = 2; i <= n; ++i) { x1_ = calX(t1[i - 1], 1, 2); y1_ = calY(t1[i - 1], 1, 2); x2_ = calX(t1[i], 1, 2); y2_ = calY(t1[i], 1, 2); edge.push_back({i - 1, i, calDis()}); } for (int i = 2; i <= m; ++i) { x1_ = calX(t2[i - 1], 3, 4); y1_ = calY(t2[i - 1], 3, 4); x2_ = calX(t2[i], 3, 4); y2_ = calY(t2[i], 3, 4); edge.push_back({i - 1 + n, i + n, calDis()}); } }
inline void build() { int pre = 1, st = 1, ed = m; for (int i = 1; i <= n; ++i) { x1_ = calX(t1[i], 1, 2); y1_ = calY(t1[i], 1, 2); if (i != 1) { st = max(1, pre - SeeRange); ed = min(m, pre + SeeRange); } dwb minDis = INF; int match = st; for (int j = st; j <= ed; ++j) { x2_ = calX(t2[j], 3, 4); y2_ = calY(t2[j], 3, 4); dwb dis = calDis(); if (dis < minDis) minDis = dis, match = j; } pre = match; int add_st = max(1, match - AddRange); int add_ed = min(m, match + AddRange); for (int j = add_st; j <= add_ed; ++j) { x2_ = calX(t2[j], 3, 4); y2_ = calY(t2[j], 3, 4); edge.push_back({i, j + n, calDis()}); } } }
int main() { init(); build(); kruskal(); return 0; }
|