POJ 3241 Object Clustering(Manhattan MST)
題目鏈接:http://poj.org/problem?id=3241
Description
We have?N?(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?(a,?b?≤ 500). The resemblance of object?i?and object?j?is defined by?dij?= |ai?-?aj| + |bi?-?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?(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\n", kruskal()); 129 } 130 } 131 132 int main() { 133 Bilibili::mymain(); 134 } View Code?
轉載于:https://www.cnblogs.com/oyking/p/4264750.html
總結
以上是生活随笔為你收集整理的POJ 3241 Object Clustering(Manhattan MST)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用指针数组实现这两个矩阵的相乘
- 下一篇: python 批量更换图片格式脚本