• 51nod-1213: 二维曼哈顿距离最小生成树


    【传送门:51nod-1213


    简要题意:

      给出平面直角坐标系中的n个点,求出这n个点的曼哈顿距离构成的完全图的最小生成树的大小


    题解:

      曼哈顿距离最小生成树的证明

      实际上有影响的边远远小于n2,在处理边的时候用树状数组维护就好了

      最后对得到的边做kruscal就行了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    struct sit
    {
        int x,y,t;
    }S[51000],P[51000];
    bool cmpx(sit n1,sit n2){return n1.x==n2.x?n1.y>n2.y:n1.x>n2.x;}
    struct LS
    {
        int x,z,id;
    }A[51000];int z;
    bool cmp1(LS n1,LS n2){return n1.x<n2.x;}
    bool cmp2(LS n1,LS n2){return n1.id<n2.id;}
    int n;
    void ls()
    {
        for(int i=1;i<=n;i++) A[i].x=P[i].x-P[i].y,A[i].id=i;
        sort(A+1,A+n+1,cmp1);
        z=1;A[1].z=1;
        for(int i=2;i<=n;i++)
        {
            if(A[i].x!=A[i-1].x) z++;
            A[i].z=z;
        }
        sort(A+1,A+n+1,cmp2);
    }
    int a[51000],p[51000];
    int lowbit(int x){return x&-x;}
    void change(int x,int d,int pos)
    {
        while(x<=z)
        {
            if(a[x]>d) a[x]=d,p[x]=pos;
            x+=lowbit(x);
        }
    }
    int getmin(int x)
    {
        int ans=a[0],t=-1;
        while(x!=0)
        {
            if(a[x]<ans) ans=a[x],t=p[x];
            x-=lowbit(x);
        }
        return t;
    }
    int dis(sit n1,sit n2){return abs(n1.x-n2.x)+abs(n1.y-n2.y);}
    struct edge
    {
        int x,y,d;
    }e[210000];
    bool cmpd(edge n1,edge n2){return n1.d<n2.d;}
    int fa[51000];
    int findfa(int x)
    {
        if(fa[x]!=x) fa[x]=findfa(fa[x]);
        return fa[x];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&S[i].x,&S[i].y);
            P[i]=S[i];
            P[i].t=i;
        }
        int len=0;
        for(int i=1;i<=4;i++)
        {
            if(i==2||i==4) for(int i=1;i<=n;i++) swap(P[i].x,P[i].y);
            else if(i==3) for(int i=1;i<=n;i++) P[i].x=-P[i].x;
            sort(P+1,P+n+1,cmpx);
            ls();
            memset(a,63,sizeof(a));
            for(int i=1;i<=n;i++)
            {
                int t=getmin(A[i].z);
                change(A[i].z,P[i].x+P[i].y,P[i].t);
                if(t==-1) continue;
                else
                {
                    int x=P[i].t,y=t;
                    e[++len]=(edge){x,y,dis(S[x],S[y])};
                }
            }
        }
        sort(e+1,e+len+1,cmpd);
        LL ans=0;
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<=len;i++)
        {
            int fx=findfa(e[i].x),fy=findfa(e[i].y);
            if(fx!=fy)
            {
                fa[fx]=fy;
                ans+=e[i].d;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    Kafka 文档用例
    Kafka 文档引言
    关于工作流核心选择
    IEEE浮点标准
    新项目的CQRS设计
    持续集成:CruiseControl.NET + VisualSVN.Server
    商城(一)
    Maven基础学习(一)—Maven入门
    Mybatis基础学习(五)—缓存
    Mybatis基础学习(四)—关系映射
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9808611.html
Copyright © 2020-2023  润新知