BZOJ 2177: 曼哈顿最小生成树 曼哈顿最小生成树
2018-01-22 20:49
260 查看
2177: 曼哈顿最小生成树
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 281 Solved: 117
[Submit][Status][Discuss]
Description
平面坐标系xOy内,给定n个顶点V = (x , y)。对于顶点u、v,u与v之间的距离d定义为|xu – xv| + |yu – yv|你的任务就是求出这n个顶点的最小生成树。
Input
第一行一个正整数n,表示定点个数。接下来n行每行两个正整数x、y,描述一个顶点。
Output
只有一行,为最小生成树的边的距离和。Sample Input
41 0
0 1
0 -1
-1 0
Sample Output
6HINT
对于100%的数据n <= 50000;0 <= x, y <= 100000。
#include<cmath> #include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<map> #include<set> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return x*f; } void print(int x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');} const int N=50100,inf=0X3f3f3f3f; int ecnt; struct EDGE { int u,v,val; friend bool operator <(const EDGE &x,const EDGE &y) {return x.val<y.val;} }e[N<<3]; struct node { int x,y,pos; friend bool operator <(const node &x,const node &y) {return x.x==y.x ? x.y<y.y : x.x<y.x;} }p ; inline int dis(int x,int y) {return abs(p[x].x-p[y].x)+abs(p[x].y-p[y].y);} int n; int V ,tot; int bit ,mn ; void initial() { register int i; sort(p+1,p+1+n); memset(mn,0,sizeof(mn)); memset(bit,0X3f,sizeof(bit)); for(i=1;i<=n;++i) V[i]=p[i].y-p[i].x; sort(V+1,V+1+n); for(i=2,tot=1;i<=n;++i) if(V[i]!=V[i-1]) V[++tot]=V[i]; } inline int get_hash(int x) { register int l(1),r(tot),mid; while(l<=r) { mid=(l+r)>>1; V[mid]<=x ? l=mid+1 : r=mid-1 ; } return l-1; } inline void modify(int x,int val,int pos) { for(;x;x-=(x&-x)) if(val<bit[x]) bit[x]=val,mn[x]=pos; } inline int query(int x) { int res(0),now(inf); for(;x<=tot;x+=(x&-x)) if(bit[x]<now) now=bit[x],res=mn[x]; return res; } int Fa ; inline int find(int x) {return Fa[x]==x ? x : Fa[x]=find(Fa[x]);} ll ans=0; void kruscal() { register int i; sort(e+1,e+1+ecnt); for(i=1;i<=n;++i) Fa[i]=i; for(i=1;i<=ecnt;++i) if(find(e[i].u)!=find(e[i].v)) Fa[Fa[e[i].u]]=Fa[e[i].v],ans+=e[i].val; } int main() { n=read(); //quadrant qd register int i,qd,pos,tmp; for(i=1;i<=n;++i) p[i].x=read(),p[i].y=read(),p[i].pos=i; for(qd=1;qd<5;++qd) { if(!(qd&1)) for(i=1;i<=n;++i) swap(p[i].x,p[i].y); else if(qd==3) for(i=1;i<=n;++i) p[i].x=-p[i].x; initial(); for(i=n;i;i--) { pos=get_hash(p[i].y-p[i].x); tmp=query(pos); if(tmp) e[++ecnt]=(EDGE){p[i].pos,p[tmp].pos,dis(i,tmp)}; modify(pos,p[i].x+p[i].y,i); } } kruscal(); cout<<ans<<endl; return 0; }
相关文章推荐
- BZOJ 2177 [曼哈顿最小生成树]
- 【BZOJ-2177】曼哈顿最小生成树 Kruskal + 树状数组
- BZOJ 2177 最小曼哈顿生成树
- [BZOJ2177][最小/最大(曼哈顿距离)生成树]曼哈顿最小生成树
- bzoj2177/51nod-1213 曼哈顿距离最小生成树
- BZOJ.2177.曼哈顿最小生成树(Kruskal)
- 曼哈顿距离最小生成树与莫队算法 (BZOJ2038)
- bzoj 1016 最小生成树计数
- BZOJ 3714: [PA2014]Kuglarz(最小生成树)
- MST——BZOJ1016 [JSOI2008]最小生成树计数
- 【最小生成树】Bzoj1601[Usaco2008 Oct]灌水
- poj 3241 Object Clustering (曼哈顿距离最小生成树)
- [BZOJ 1016][JSOI2008]最小生成树计数(Kruskal)
- [BZOJ2521][Shoi2010]最小生成树(最小割)
- [XOR最小生成树 期望 DP] BZOJ 4770 图样
- BZOJ1232: [Usaco2008Nov]安慰奶牛cheer 最小生成树 Kruskal
- bzoj 1941 kd-tree求最大最小曼哈顿距离
- 曼哈顿距离最小生成树
- 【BZOJ3669】[Noi2014]魔法森林【Link-Cut Tree】【最小生成树】
- 图的绝对中心(bzoj 2180: 最小直径生成树)