zoukankan      html  css  js  c++  java
  • [51nod1213]二维曼哈顿距离最小生成树

      二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间的距离为:横纵坐标的差的绝对值之和,即:Abs(x1 - x2) + Abs(y1 - y2)(也称曼哈顿距离)。求这N个点所组成的完全图的最小生成树的边权之和。
     Input
      第1行:1个数N,表示点的数量。(2 <= N <= 50000)
      第2 - N + 1行:每行2个数,表示点的坐标(0 <= x, y <= 1000000)
     Output
      输出N个点所组成的完全图的最小生成树的边权之和。

    就当是攒新板子了。。

    题解:http://blog.csdn.net/acm_cxlove/article/details/8890003

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #include<cstdlib>
     8 #define ll long long
     9 #define ull unsigned long long
    10 #define ui unsigned int
    11 //#define d double
    12 #define ld long double
    13 const int maxn=50023,inf=1002333333;
    14 struct zs{int x,y,v,id;}a[maxn],aa[maxn],e[maxn<<2];int ne;
    15 struct zs1{int v,id;}t[maxn],b[maxn];
    16 int fa[maxn];
    17 int i,j,k,n,m;
    18 ll ans;
    19 
    20 int ra,fh;char rx;
    21 inline int read(){
    22     rx=getchar(),ra=0,fh=1;
    23     while(rx<'0'&&rx!='-')rx=getchar();
    24     if(rx=='-')fh=-1,rx=getchar();
    25     while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra*fh;
    26 }
    27 
    28 inline int abs(int x){return x<0?-x:x;}
    29 inline int getdis(int a,int b){
    30     return abs(aa[a].x-aa[b].x)+abs(aa[a].y-aa[b].y);
    31 }
    32 inline void insert(int a,int b){
    33     /*e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
    34     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot,
    35     e[tot-1].dis=e[tot].dis=getdis(a,b);*/
    36     e[++ne]=(zs){a,b,getdis(a,b)};
    37 }
    38 
    39 bool operator <(zs a,zs b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    40 bool operator <(zs1 a,zs1 b){return a.v<b.v;}
    41 bool cmpe(zs a,zs b){return a.v<b.v;}
    42 
    43 inline void mins(zs1 &a,zs1 b){if(b.v<a.v)a=b;}
    44 inline void add(int x,zs1 mn){while(x<=n)mins(t[x],mn),x+=x&-x;}
    45 inline int query(int x){zs1 mn=(zs1){inf,-23};while(x)mins(mn,t[x]),x-=x&-x;return mn.id;}
    46 inline void run(){
    47     int i,cnt=0;
    48     for(i=1;i<=n;i++)t[i]=(zs1){inf,-23};
    49     for(i=1;i<=n;i++)b[i]=(zs1){a[i].y-a[i].x,i};
    50     std::sort(b+1,b+1+n);
    51     for(i=1;i<=n;a[b[i].id].v=n-cnt+1,i++)cnt+=b[i].v!=b[i-1].v||i==1;
    52     std::sort(a+1,a+1+n);
    53     for(i=n;i;i--){
    54         int id=query(a[i].v);
    55         if(id>0)insert(a[i].id,id);
    56         add(a[i].v,(zs1){a[i].x+a[i].y,a[i].id});
    57     }
    58 }
    59 
    60 inline int getfa(int x){return fa[x]!=x?fa[x]=getfa(fa[x]):x;}
    61 int main(){
    62     n=read();
    63     for(i=1;i<=n;i++)aa[i].x=read(),aa[i].y=read();
    64     
    65     for(i=1;i<=n;i++)a[i].x=aa[i].x,a[i].y=aa[i].y,a[i].id=i;
    66     run();
    67     
    68     for(i=1;i<=n;i++)a[i].x=aa[i].x,a[i].y=-aa[i].y,a[i].id=i;
    69     run();
    70     
    71     for(i=1;i<=n;i++)a[i].x=aa[i].y,a[i].y=aa[i].x,a[i].id=i;
    72     run();
    73     
    74     for(i=1;i<=n;i++)a[i].x=-aa[i].y,a[i].y=aa[i].x,a[i].id=i;
    75     run();
    76     
    77     std::sort(e+1,e+1+ne,cmpe);
    78     for(i=1;i<=n;i++)fa[i]=i;
    79     for(i=1;i<=ne;i++)if(getfa(e[i].x)!=getfa(e[i].y))
    80         fa[fa[e[i].x]]=fa[e[i].y],ans+=e[i].v;
    81     printf("%lld
    ",ans);
    82 }
    View Code
  • 相关阅读:
    字符个数统计
    面试题——字符的左右移动
    5. Longest Palindromic Substring
    Linux- AWS之EC2大数据集群定时开关机
    Openldap- 大机群身份验证服务
    Linux- 自动备份MySQL数据库脚本
    Linux- 运维
    JAVA- 切换默认的Java
    HIVE- 新建UDF范例
    Hadoop- 集群启动详解
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5949140.html
Copyright © 2011-2022 走看看