首页 > 其他 > 详细

POJ 3241 曼哈顿距离最小生成树 Object Clustering

时间:2015-09-24 10:46:31      阅读:209      评论:0      收藏:0      [点我收藏+]

先上几个资料:

百度文库有详细的分析和证明

cxlove的博客

TopCoder Algorithm Tutorials

 

技术分享
#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\n", ans);
    }

    return 0;
}
代码君

 

POJ 3241 曼哈顿距离最小生成树 Object Clustering

原文:http://www.cnblogs.com/AOQNRMGYXLMV/p/4834352.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!