二维平面上有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 }