[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\n",ans);
82 }
View Code

 

posted @ 2016-10-11 14:26  czllgzmzl  阅读(424)  评论(0编辑  收藏  举报