2010 Mid-Atlantic Regional Programming Contest H题 Underground Cables 分析&解题报告
来源:互联网 发布:mysql updata 编辑:程序博客网 时间:2024/05/16 05:12
传送门:http://acm.hnu.cn/online/?action=problem&type=show&id=12126&courseid=196
裸的最小生成树。其中还有到了一条性质,就是本题中,最小生成树不可能有交叉。
证:
如果有交叉,比如上图的AC和BD,因为AE+ED>AD,BE+EC>BC,那么加上AD和BC后去掉AC和BD将得到一棵更小的树。所以这不可能是最小生成树。
这里我用的是prim算法,下面列出了两种实现:
1.朴素实现,通过数组dist[i]存储非树T内节点i到树T的最小距离,每次加入新节点时更新一次。bool数组vis[i]=true代表该点在树中。复杂度Θ(n^2)。
2.通过基于最小二叉堆的优先队列来实现。P类表示点,数据成员dist是该点到树的最短距离,id表示该点的序号。复杂度算了下貌似是O(n^2*lgn)。不是优化吗?复杂度怎么还大了。。。
1.125ms 2.140ms 果然。。。
推荐读物:《算法导论》,Thomas H.Cormen等。
CODE1:
//mst O(n^2)#include<iostream>#include<memory.h>#include<cmath>#include<fstream>#include<iomanip>using namespace std;double map[1001][1001];int N,num;int coo[1001][2];bool vis[1001];double dist[1001];double ans;int main(){ //ifstream cin("in1.txt"); //ofstream cout("out1.txt"); while(cin>>N&&N) { memset(vis,false,sizeof(vis)); ans=num=0; for(int i=1;i<=N;i++) cin>>coo[i][0]>>coo[i][1]; for(int i=1;i<=N;i++) for(int j=i;j<=N;j++) map[j][i]=map[i][j]=sqrt((coo[i][0]-coo[j][0])*(coo[i][0]-coo[j][0])+(coo[i][1]-coo[j][1])*(coo[i][1]-coo[j][1])); int minid; double min; vis[1]=true; num++; for(int i=2;i<=N;i++) dist[i]=map[1][i]; while(num<N) { min=10000000.0; for(int i=1;i<=N;i++) if(!vis[i]&&dist[i]<min) { min=dist[i]; minid=i; } ans+=min; vis[minid]=true; num++; for(int i=1;i<=N;i++) if(!vis[i]&&map[minid][i]<dist[i]) dist[i]=map[minid][i]; } cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<endl; }return 0;}
CODE2:
#include<iostream>#include<cmath>#include<fstream>#include<iomanip>using namespace std;class P{ public: int id; double dist;};int N,heap_size;P A[1001];double map[1001][1001];int coo[1001][2];double ans;void Min_heapify(int i){ int l=i<<1; int r=(i<<1)+1; int min=i; if(l<=heap_size&&A[l].dist<A[min].dist) min=l; if(r<=heap_size&&A[r].dist<A[min].dist) min=r; if(A[min].dist==A[i].dist) return; else { double t1=A[i].dist; int t2=A[i].id; A[i].dist=A[min].dist; A[i].id=A[min].id; A[min].dist=t1; A[min].id=t2; Min_heapify(min); }}void Build_min_heap(){ for(int i=heap_size/2;i>=1;i--) Min_heapify(i);}P Heap_extract_min(){ P min; min.dist=A[1].dist; min.id=A[1].id; A[1].dist=A[heap_size].dist; A[1].id=A[heap_size].id; heap_size--; Min_heapify(1); return min;}void Min_decrease_key(int i,double key){ A[i].dist=key; while(i>1&&A[i/2].dist>A[i].dist) { double t1=A[i].dist; int t2=A[i].id; A[i].dist=A[i/2].dist; A[i].id=A[i/2].id; A[i/2].dist=t1; A[i/2].id=t2; i=i/2; }}int main(){ //ifstream cin("in1.txt"); while(cin>>N&&N) { heap_size=N-1; ans=0; for(int i=1;i<=N;i++) cin>>coo[i][0]>>coo[i][1]; for(int i=1;i<=N;i++) for(int j=i;j<=N;j++) map[j][i]=map[i][j]=sqrt((coo[i][0]-coo[j][0])*(coo[i][0]-coo[j][0])+(coo[i][1]-coo[j][1])*(coo[i][1]-coo[j][1])); for(int i=2;i<=N;i++) { A[i-1].dist=map[i][1]; A[i-1].id=i; } Build_min_heap(); while(heap_size>0) { P t=Heap_extract_min(); ans+=t.dist; for(int i=1;i<=heap_size;i++) if(map[A[i].id][t.id]<A[i].dist) Min_decrease_key(i,map[A[i].id][t.id]); } cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<endl; }return 0;}
- 2010 Mid-Atlantic Regional Programming Contest H题 Underground Cables 分析&解题报告
- 2013 Asia Regional Contest A题 意外 解题报告
- 2013 Asia Regional Contest C题 解题报告
- 2012 East Central Regional Contest 解题报告
- Underground Cables
- ACM Asia Regional (Kanpur Site) Programming Contest 2001 Problem H
- J - Underground Cables
- 2013 Chengdu Regional H - Hard Disk Drive解题报告
- The 11th Zhejiang University Programming Contest / 解题报告 4.3
- The University of Chicago Invitational Programming Contest 2012 解题报告
- Arab Collegiate Programming Contest 2012 解题报告(约等于AK)
- The 2006 Benelux Algorithm Programming Contest 解题报告
- 2075 Tangled in Cables 解题报告
- Southeastern European Regional Programming Contest 2010 D Problemsetting
- H - Happy Programming Contest
- 2014 Asia Kuala Lumpur Regional Contest(吉隆坡2014)解题报告汇总
- 2014-2015 ACM-ICPC Northeastern European Regional Contest (NEERC 14) 解题报告
- 131014 Regionals 2010, North America - Mid-Atlantic USA
- FF添加innerText属性
- ubuntu server下无界面安装oracle笔记
- 《那些年啊,那些事——一个程序员的奋斗史》——24
- opencv使用频域相乘加速卷积速度
- openssl生成https证书
- 2010 Mid-Atlantic Regional Programming Contest H题 Underground Cables 分析&解题报告
- Linux 下 Makefile 的 automake 生成举例 "hello world"
- Hbase 版本变化困惑
- 创建可被取消的默认事件处理器
- 关于linux下make详细用法
- objective-c内存管理方面
- 部署应用程序到Android手机
- 從軟件開發角度看全對偶測試法
- openfire插件开发简单实例