[BZOJ2177][最小/最大(曼哈顿距离)生成树]曼哈顿最小生成树
来源:互联网 发布:全国书画艺术网络大赛 编辑:程序博客网 时间:2024/04/30 22:24
题意
给定平面内一些点,求最小曼哈顿距离生成树
看这篇咯http://blog.csdn.net/acm_cxlove/article/details/8890003
#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>#define N 100010#define X first#define Y secondusing namespace std;typedef long long ll;int n,m,cnt,cnt0;int B[N],C[N],D[N],fa[N];ll Ans;struct Point{ int x,y,id;}A[N];struct edge{ int u,v,w; edge(int u=0,int v=0):u(u),v(v){} friend bool operator <(edge a,edge b){ return a.w<b.w; }}E[N<<3];inline bool cmpx(Point a,Point b){ return a.x<b.x;}inline bool cmpy(Point a,Point b){ return a.y<b.y;}inline bool back(Point a,Point b){ return a.id<b.id;}inline void reaD(int &x){ char c=getchar(); x=0; int f=1; for(;c>'9'||c<'0';c=getchar())if(c=='-') f=-1; for(;c>='0'&&c<='9';x=x*10+c-'0',c=getchar()); x*=f;}inline int query(int x){ int Min=1<<30,r=-1; for(;x<=cnt;x+=x&-x) if(C[x]<Min) Min=C[x],r=D[x]; return r;}inline void Add(int x,int y,int z){ for(;x;x-=x&-x) if(y<C[x]) C[x]=y,D[x]=z;}int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]);}int main(){ reaD(n); for(int i=1;i<=n;i++) reaD(A[i].x),reaD(A[i].y),A[i].id=i; for(int i=1;i<=n;i++) B[i]=A[i].y-A[i].x; //1 sort(A+1,A+1+n,cmpx); sort(B+1,B+1+n); cnt=unique(B+1,B+1+n)-B-1; memset(C,0x7f,sizeof(C)); memset(D,-1,sizeof(D)); for(int i=n;i;i--){ int x=lower_bound(B+1,B+1+cnt,A[i].y-A[i].x)-B,pos=query(x); if(pos>0) E[++cnt0]=edge(A[i].id,pos); Add(x,A[i].x+A[i].y,A[i].id); } //4 memset(C,0x7f,sizeof(C)); memset(D,-1,sizeof(D)); for(int i=1;i<=n;i++) B[i]=-A[i].x-A[i].y; sort(B+1,B+1+n); cnt=unique(B+1,B+1+n)-B-1; for(int i=n;i;i--){ int x=lower_bound(B+1,B+1+cnt,-A[i].x-A[i].y)-B,pos=query(x); if(pos>0) E[++cnt0]=edge(A[i].id,pos); Add(x,A[i].x-A[i].y,A[i].id); } //2 sort(A+1,A+1+n,cmpy); memset(C,0x7f,sizeof(C)); memset(D,-1,sizeof(D)); for(int i=1;i<=n;i++) B[i]=A[i].x-A[i].y; sort(B+1,B+1+n); cnt=unique(B+1,B+1+n)-B-1; for(int i=n;i;i--){ int x=lower_bound(B+1,B+1+cnt,A[i].x-A[i].y)-B,pos=query(x); if(pos>0) E[++cnt0]=edge(A[i].id,pos); Add(x,A[i].x+A[i].y,A[i].id); } //3 memset(C,0x7f,sizeof(C)); memset(D,-1,sizeof(D)); for(int i=1;i<=n;i++) B[i]=A[i].y+A[i].x; sort(B+1,B+1+n); cnt=unique(B+1,B+1+n)-B-1; for(int i=1;i<=n;i++){ //printf("%d\n",i); int x=lower_bound(B+1,B+1+cnt,A[i].y+A[i].x)-B,pos=query(x); if(pos>0) E[++cnt0]=edge(A[i].id,pos); Add(x,A[i].x-A[i].y,A[i].id); } //mst sort(A+1,A+1+n,back); for(int i=1;i<=cnt0;i++) E[i].w=abs(A[E[i].u].x-A[E[i].v].x)+abs(A[E[i].u].y-A[E[i].v].y); sort(E+1,E+1+cnt0); //for(int i=1;i<=cnt0;i++) printf("%d %d %d\n",E[i].u,E[i].v,E[i].w); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=cnt0;i++){ if(find(E[i].u)==find(E[i].v)) continue; fa[find(E[i].u)]=find(E[i].v); Ans+=E[i].w; } cout<<Ans<<endl; return 0;}
另外还有求最大曼哈顿距离生成树,好像有个叫Boruvka的算法
就是每次找到图中独立的一个团,找到一条最长的一个端点在这个团中另一个端点属于另一个团的边,把这两个端点属于的团合并,记录答案。
#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <algorithm>#include <vector>#include <set>#define N 100010#define X first#define Y secondusing namespace std;typedef long long ll;typedef pair<int,int> paris;typedef pair<ll,paris> parpar;typedef set<paris>::iterator itr;int n;int fa[N],vis[N];int val[N][4];paris p[N];ll Ans;set<paris> S[4];vector<parpar> A;vector<int> V[N];int dx[4]={1,1,-1,-1},dy[4]={1,-1,-1,1};inline void reaD(int &x){ char c=getchar();x=0; int f=1; for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-1; for(;c>='0'&&c<='9';x=x*10+c-'0',c=getchar()); x*=f;}int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); }inline bool iUnion(int x,int y){ x=find(x); y=find(y); if(x==y) return 0; if(V[x].size()>V[y].size()) swap(x,y); for(int i=0;i<V[x].size();i++) V[y].push_back(V[x][i]); V[x].clear(); fa[x]=y; return 123;}int main(){ freopen("mst.in","r",stdin); freopen("mst.out","w",stdout); reaD(n); for(int i=1;i<=n;i++) reaD(p[i].X),reaD(p[i].Y); for(int i=1;i<=n;i++){ fa[i]=i,V[i].push_back(i); for(int j=0;j<4;j++){ val[i][j]=p[i].X*dx[j]+p[i].Y*dy[j]; S[j].insert(paris(val[i][j],i)); } } int linked=0; while(!linked){ memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ int x=find(i); if(vis[x]) continue; if(V[x].size()==n){ linked=1; break; } vis[x]=1; for(int j=0;j<V[x].size();j++){ int u=V[x][j]; for(int k=0;k<4;k++) S[k].erase(paris(val[u][k],u)); } int v; ll Max=-1; for(int j=0;j<V[x].size();j++){ int u=V[x][j]; for(int k=0;k<4;k++){ itr it=S[(k+2)%4].end(); it--; if(1ll*it->X+val[u][k]>Max) Max=1ll*it->X+val[u][k],v=it->Y; } } A.push_back(parpar(Max,paris(x,v))); for(int j=0;j<V[x].size();j++){ int u=V[x][j]; for(int k=0;k<4;k++) S[k].insert(paris(val[u][k],u)); } } for(int i=0;i<A.size();i++){ int u=A[i].Y.X,v=A[i].Y.Y; ll w=A[i].X; if(iUnion(u,v)) Ans+=w; } } cout<<Ans<<endl; return 0;}
0 0
- [BZOJ2177][最小/最大(曼哈顿距离)生成树]曼哈顿最小生成树
- bzoj2177/51nod-1213 曼哈顿距离最小生成树
- 曼哈顿距离最小生成树
- 曼哈顿距离最小生成树
- 曼哈顿距离最小生成树
- 曼哈顿最小生成树
- 曼哈顿最小距离生成树(poj 3241&& UVALive 3662)
- POJ 3241 (曼哈顿距离最小生成树)
- 平面曼哈顿最小生成树
- poj3241 曼哈顿最小生成树
- 二维曼哈顿最小生成树
- 关于曼哈顿距离下的最小生成树
- 曼哈顿距离最小生成树与莫队算法
- POJ 3241 Object Clustering (曼哈顿距离最小生成树)
- 曼哈顿距离最小生成树与莫队算法
- POJ 3241 Object Clustering 曼哈顿距离最小生成树
- 曼哈顿距离最小生成树与莫队算法
- 二维平面曼哈顿距离最小生成树模版
- js+dom娱乐之一个夸张的倒计时
- web前端px和rem自动转换插件
- Spring面向切面编程
- Ubuntu14.04安装OpenCV2.4.13(ZIP安装)
- 蓝桥杯历届试题——九宫重排(启发式搜索)
- [BZOJ2177][最小/最大(曼哈顿距离)生成树]曼哈顿最小生成树
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- Nginx简单入门教学,包学包会,让你不再依赖伪大神!
- 【九度OJ】题目1467:二叉排序树 解题报告
- Java基础学习之队列和泛型
- Java关键字之static
- Android通过tcpdump抓包
- 爬虫爬到含空格的url的处理办法
- 博客实现浏览量统计次数