• POJ 3241 Object Clustering(Manhattan MST)


    题目链接:http://poj.org/problem?id=3241

    Description

    We have (N ≤ 10000) objects, and wish to classify them into several groups by judgement of their resemblance. To simply the model, each object has 2 indexes a and b (ab ≤ 500). The resemblance of object i and object j is defined by dij = |a- aj| + |b- bj|, and then we say i is dij resemble to j. Now we want to find the minimum value of X, so that we can classify the N objects into K (< N) groups, and in each group, one object is at most X resemble to another object in the same group, i.e, for every object i, if i is not the only member of the group, then there exists one object j (i ≠ j) in the same group that satisfies dij ≤ X

    Input

    The first line contains two integers N and K. The following N lines each contain two integers a and b, which describe a object.

    Output

    A single line contains the minimum X.

    题目大意:给n个点,两个点之间的距离为曼哈顿距离。要求把n个点分成k份,每份构成一个连通的子图(树),要求最大边最小。求最大边的最小值。

    思路:实际上就是求平面上曼哈顿距离的最小生成树的第k大边(即减掉最大的k-1条边构成k份)。

    资料:曼哈顿MST。复杂度O(nlogn)。

    http://wenku.baidu.com/view/1e4878196bd97f192279e941.html

    http://blog.csdn.net/huzecong/article/details/8576908

    代码(79MS):

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 typedef long long LL;
      7 #define FOR(i, n) for(int i = 0; i < n; ++i)
      8 
      9 namespace Bilibili {
     10     const int MAXV = 10010;
     11     const int MAXE = MAXV * 4;
     12 
     13     struct Edge {
     14         int u, v, cost;
     15         Edge(int u = 0, int v = 0, int cost = 0):
     16             u(u), v(v), cost(cost) {}
     17         bool operator < (const Edge &rhs) const {
     18             return cost < rhs.cost;
     19         }
     20     };
     21 
     22     struct Point {
     23         int x, y, id;
     24         void read(int i) {
     25             id = i;
     26             scanf("%d%d", &x, &y);
     27         }
     28         bool operator < (const Point &rhs) const {
     29             if(x != rhs.x) return x < rhs.x;
     30             return y < rhs.y;
     31         }
     32     };
     33 
     34     Point p[MAXV];
     35     Edge edge[MAXE];
     36     int x_plus_y[MAXV], y_sub_x[MAXV];
     37     int n, k, ecnt;
     38 
     39     int hash[MAXV], hcnt;
     40 
     41     void get_y_sub_x() {
     42         for(int i = 0; i < n; ++i) hash[i] = y_sub_x[i] = p[i].y - p[i].x;
     43         sort(hash, hash + n);
     44         hcnt = unique(hash, hash + n) - hash;
     45         for(int i = 0; i < n; ++i) y_sub_x[i] = lower_bound(hash, hash + hcnt, y_sub_x[i]) - hash + 1;
     46     }
     47 
     48     void get_x_plus_y() {
     49         for(int i = 0; i < n; ++i) x_plus_y[i] = p[i].x + p[i].y;
     50     }
     51 
     52     int tree[MAXV];
     53     int lowbit(int x) {
     54         return x & -x;
     55     }
     56 
     57     void update_min(int &a, int b) {
     58         if(b == -1) return ;
     59         if(a == -1 || x_plus_y[a] > x_plus_y[b])
     60             a = b;
     61     }
     62 
     63     void initBit() {
     64         memset(tree + 1, -1, hcnt * sizeof(int));
     65     }
     66 
     67     void modify(int x, int val) {
     68         while(x) {
     69             update_min(tree[x], val);
     70             x -= lowbit(x);
     71         }
     72     }
     73 
     74     int query(int x) {
     75         int res = -1;
     76         while(x <= hcnt) {
     77             update_min(res, tree[x]);
     78             x += lowbit(x);
     79         }
     80         return res;
     81     }
     82 
     83     void build_edge() {
     84         sort(p, p + n);
     85         get_x_plus_y();
     86         get_y_sub_x();
     87         initBit();
     88         for(int i = n - 1; i >= 0; --i) {
     89             int tmp = query(y_sub_x[i]);
     90             if(tmp != -1) edge[ecnt++] = Edge(p[i].id, p[tmp].id, x_plus_y[tmp] - x_plus_y[i]);
     91             modify(y_sub_x[i], i);
     92         }
     93     }
     94 
     95     int fa[MAXV], ans[MAXV];
     96 
     97     int find_set(int x) {
     98         return fa[x] == x ? x : fa[x] = find_set(fa[x]);
     99     }
    100 
    101     int kruskal() {
    102         for(int i = 0; i < n; ++i) fa[i] = i;
    103         sort(edge, edge + ecnt);
    104         int acnt = 0;
    105         for(int i = 0; i < ecnt; ++i) {
    106             int fu = find_set(edge[i].u), fv = find_set(edge[i].v);
    107             if(fu != fv) {
    108                 ans[acnt++] = edge[i].cost;
    109                 fa[fu] = fv;
    110             }
    111         }
    112         reverse(ans, ans + acnt);
    113         return ans[k - 1];
    114     }
    115 
    116     void mymain() {
    117         scanf("%d%d", &n, &k);
    118         for(int i = 0; i < n; ++i) p[i].read(i);
    119 
    120         build_edge();
    121         for(int i = 0; i < n; ++i) swap(p[i].x, p[i].y);
    122         build_edge();
    123         for(int i = 0; i < n; ++i) p[i].x = -p[i].x;
    124         build_edge();
    125         for(int i = 0; i < n; ++i) swap(p[i].x, p[i].y);
    126         build_edge();
    127 
    128         printf("%d
    ", kruskal());
    129     }
    130 }
    131 
    132 int main() {
    133     Bilibili::mymain();
    134 }
    View Code
  • 相关阅读:
    外观模式
    建造者模式
    原型模式
    工厂模式
    单例模式
    设计模式入门
    SpringBoot-SpringMVC开发总结
    SpringBoot日志
    IDEA Basics
    Kafka基础学习
  • 原文地址:https://www.cnblogs.com/oyking/p/4264750.html
Copyright © 2020-2023  润新知