先上几个资料:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <cmath> using namespace std; const int maxn = 10000 + 10; const int INF = 0x3f3f3f3f; int n, m, k; struct Point { int x, y, id; bool operator < (const Point& p) const { return x < p.x || (x == p.x && y < p.y); } }; Point p[maxn]; int dist(Point a, Point b) { return abs(a.x-b.x) + abs(a.y-b.y); } struct Node { int min_val, pos; void init() { min_val = INF; pos = -1; } }; inline int lowbit(int x) { return x & (-x); } Node BIT[maxn]; struct Edge { int u, v, d; Edge(int u, int v, int d):u(u), v(v), d(d) {} bool operator < (const Edge& e) const { return d < e.d; } }; vector<Edge> edges; int pa[maxn]; int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); } int a[maxn], b[maxn]; void update(int x, int val, int pos) { while(x) { if(val < BIT[x].min_val) { BIT[x].min_val = val; BIT[x].pos = pos; } x -= lowbit(x); } } int query(int x) { int val = INF, pos = -1; while(x <= m) { if(BIT[x].min_val < val) { val = BIT[x].min_val; pos = BIT[x].pos; } x += lowbit(x); } return pos; } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d%d", &n, &k) == 2 && n) { edges.clear(); for(int i = 0; i < n; i++) { scanf("%d%d", &p[i].x, &p[i].y); p[i].id = i; } //Select edges for(int dir = 0; dir < 4; dir++) { //Coordinate Transformation if(dir == 1 || dir == 3) for(int i = 0; i < n; i++) swap(p[i].x, p[i].y); else if(dir == 2) for(int i = 0; i < n; i++) p[i].x = -p[i].x; sort(p, p + n); for(int i = 0; i < n; i++) a[i] = b[i] = p[i].y - p[i].x; sort(b, b + n); m = unique(b, b + n) - b; for(int i = 1; i <= m; i++) BIT[i].init(); for(int i = n - 1; i >= 0; i--) { int pos = lower_bound(b, b + m, a[i]) - b + 1; int q = query(pos); if(q != -1) edges.push_back(Edge(p[i].id, p[q].id, dist(p[i], p[q]))); update(pos, p[i].x + p[i].y, i); } } //Kruskal sort(edges.begin(), edges.end()); int cnt = n - k, ans; for(int i = 0; i < n; i++) pa[i] = i; for(int i = 0; i < edges.size(); i++) { int u = edges[i].u, v = edges[i].v; int pu = findset(u), pv = findset(v); if(pu != pv) { if(--cnt == 0) { ans = edges[i].d; break; } pa[pu] = pv; } } printf("%d ", ans); } return 0; }