zoukankan      html  css  js  c++  java
  • POJ 3241 曼哈顿距离最小生成树 Object Clustering

    先上几个资料:

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

    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
    ", ans);
        }
    
        return 0;
    }
    代码君
  • 相关阅读:
    Install the Maven in your computer
    《李嘉诚全传》--孙良珠
    Crystal Reports 2008(水晶报表) 第一个报表
    《唤醒心中的巨人》--[美]安东尼·罗宾
    《写给女人》--[美]桃乐丝·卡耐基
    Crystal Reports 2008(水晶报表) JDBC连接mysql数据库
    Crystal Reports 2008(水晶报表) 启动时检查更新
    Crystal Reports 2008(水晶报表) 安装
    《百年孤独》--[哥伦比亚]加夫列尔·加西亚·马尔克斯
    《自己拯救自己》--[英]塞缪尔·斯迈尔斯
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4834352.html
Copyright © 2011-2022 走看看