Another Minimum Spanning Tree - UVaLive 3662 曼哈顿最小生成树
2015-06-14 12:27
405 查看
For a given point set P = {(xi, yi) : 1
i
n},
then construct a complete graph G = (V, E, W) with nvertexes. The weight function for any two vertexes is w(vi, vj)
= | xi - xj| + | yi - yj|. Please calculate the minimum spanning tree of G.
the shadow area. You can extend this property to solve the problem.
Each cases begins with an integer n, 1
n
100,
000, to indicate the size of the point set. The points in the point set have serial numbers from 1 to n.
Each line of the following n lines contains two non-negative integers (xi, yi) (no more than 107)
to describe the coordinate for each point. Any two points' coordinates are different.
The last case is followed by a line containing a zero.
题意:求曼哈顿最小生成树。
AC代码如下:
i
n},
then construct a complete graph G = (V, E, W) with nvertexes. The weight function for any two vertexes is w(vi, vj)
= | xi - xj| + | yi - yj|. Please calculate the minimum spanning tree of G.
Hint
For the graph below, there exists a minimum spanning tree in which there is at most one vertex connected withA inthe shadow area. You can extend this property to solve the problem.
Input
Input contains several cases.Each cases begins with an integer n, 1
n
100,
000, to indicate the size of the point set. The points in the point set have serial numbers from 1 to n.
Each line of the following n lines contains two non-negative integers (xi, yi) (no more than 107)
to describe the coordinate for each point. Any two points' coordinates are different.
The last case is followed by a line containing a zero.
Output
For each case, output the case's serial number and the weighted sum of all minimum spanning tree edges in the following format.Sample Input
3 0 0 2 0 0 3 0
Sample Output
Case 1: Total Weight = 5
题意:求曼哈顿最小生成树。
AC代码如下:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; struct node { int x,y,pos; }point[100010]; struct node2 { int u,v,w; }edge[40000010]; int T,t,n,N=40000020,tot,p[100010],c[40000020],d[40000020],INF=1e9; bool cmp(node a,node b) { return a.x<b.x || (a.x==b.x && a.y<b.y); } bool cmp2(node2 a,node2 b) { return a.w<b.w; } int lowbit(int x) { return x&(-x); } int find(int x) { return x==p[x] ? x : p[x]=find(p[x]); } void query(int val,int w,int pos) { int id=-1,minn=INF,i; val+=20000010; for(i=val;i<N;i+=lowbit(i)) if(c[i]<minn) { minn=c[i]; id=d[i]; } if(id!=-1) { tot++; edge[tot].u=pos; edge[tot].v=id; edge[tot].w=minn-w; } } void update(int val,int w,int pos) { int i,j,k; val+=20000010; for(i=val;i>0;i-=lowbit(i)) if(w<c[i]) { c[i]=w; d[i]=pos; } } void go() { int i,j,k; sort(point+1,point+1+n,cmp); for(i=1;i<N;i++) c[i]=INF; for(i=n;i>=1;i--) { query(point[i].y-point[i].x,point[i].y+point[i].x,point[i].pos); update(point[i].y-point[i].x,point[i].y+point[i].x,point[i].pos); } } ll work() { int i,j,k,u,v; ll ans=0; tot=0; go(); for(i=1;i<=n;i++) swap(point[i].x,point[i].y); go(); for(i=1;i<=n;i++) point[i].y=-point[i].y; go(); for(i=1;i<=n;i++) swap(point[i].x,point[i].y); go(); sort(edge+1,edge+1+tot,cmp2); for(i=1;i<=n;i++) p[i]=i; for(i=1;i<=tot;i++) { u=find(edge[i].u); v=find(edge[i].v); if(u==v) continue; p[u]=v; ans+=edge[i].w; } return ans; } int main() { int i,j,k; ll ans; while(~scanf("%d",&n) && n>0) { for(i=1;i<=n;i++) { scanf("%d%d",&point[i].x,&point[i].y); point[i].pos=i; } ans=work(); printf("Case %d: Total Weight = %lld\n",++t,ans); } }
相关文章推荐
- LIBSVM 在matlab 2013添加 VS2013 c++编译器
- 二分查找
- Leetcode[72]-Climbing Stairs
- Jquery ui autocomplete简单api
- IOS笔记048-数据存储
- SQL学习心得(转)
- ios上 更改 状态栏(UIStatusBar)的颜色
- TODO_android
- Java转义符\\|
- centos6.5升级linux内核
- java 如何避免“!=null”式的判空语句?
- iOS7 StatusBar 使用小结
- PHP学习笔记(1)——PHP中的ORM框架介绍
- 一个IOS9 网络问题
- 屏蔽无耻的百度广告
- Unity项目对 git版本控制库扩展插件
- 利用FindFirstFile(),FindNextFile()函数历遍指定目录的所有文件
- #leetcode#Jump Game II
- 单向链表总结
- PHP压缩上传图片