POJ 3241 Object Clustering 曼哈顿距离求最小生成树的第K小边

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


#include 
#include 
#include 
#include 
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
#define maxn 10005
using namespace std;

struct point
{
    int x,y,id;
    bool operator < (const point &cmp)const
    {
        if(x==cmp.x)return y=1; i-=lowbit(i))
        if(bit[i].min_val >  val)
            bit[i].min_val=val,bit[i].pos=pos;
}
int query(int x,int m)//这里其实求的是 x-m 上的最小值
{
    int val=inf,pos=-1;
    for(int i=x; i<=m; i+=lowbit(i))
        if(bit[i].min_val < val)
            val=bit[i].min_val,pos=bit[i].pos;
    return pos;
}
void addedge(int s,int e,int v)
{
    E[tot].s=s;
    E[tot].e=e;
    E[tot++].w=v;
}
int dist(int a,int b)
{
    return abs(p[a].x-p[b].x)+abs(p[a].y-p[b].y);
}
int set[maxn];
int find(int x)
{
    if(x!=set[x])
        return set[x]=find(set[x]);
    return x;
}
int a[maxn],b[maxn];
int Manhattan_MST()
{
    for(int i=1; i<=n; i++)
    {
        scanf("%d%d",&p[i].x,&p[i].y);
        p[i].id=i;
    }

    for(int dir=1; dir<=4; dir++)
    {
        if(dir==2 || dir==4)
        {
            for(int i=1; i<=n; i++)
                swap(p[i].x,p[i].y);
        }
        else if(dir==3)
            for(int i=1; i<=n; i++)
                p[i].x=-p[i].x;

        sort(p+1,p+1+n);//sort by x

        for(int i=1; i<=n; i++)
            a[i]=b[i]=p[i].y-p[i].x;

        sort(b+1,b+1+n);//将 y-x 离散化

        int m=unique(b+1,b+1+n)-b;

        for(int i=1; i=1; i--)//这里y-x从大到小进入BIT。那么这里保证了y-x 的有序。
        {
            int pos=lower_bound(b+1,b+m,a[i])-b;
            int ans = query(pos,m-1);
            if(ans!=-1)addedge(p[i].id,p[ans].id,dist(i,ans));
            update(pos,p[i].x+p[i].y,i);//求出加入到BIT中的比当前点y-x大的y+x的值。
        }
    }
    sort(E,E+tot);

    for(int i=0; i<=n; i++)set[i]=i;

    int cnt=n-k;

    for(int i=0; i


你可能感兴趣的:(莫队算法)