日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 3241 Object Clustering(Manhattan MST)

發布時間:2024/9/5 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。