zoj 1203求最小生成树的权值之和(kruskal算法实现)
2012-12-07 18:49
549 查看
这道zoj的题目,主要运用的是求最小生成树的知识,我用的是kruskal算法,当然,用取权值最小边的最小堆和查看是否有回路的并查集是自己实现的。但提交了几次都没成功,查了下,原来是自己的输出格式没有正确。看来以后要特别注意这方面的问题。
#include <iostream> #include <queue> #include <cstdio> #include <cmath> #include <memory.h> using namespace std; /**********************堆***************************/ int heapNum=0; //记录堆的结点个数 //堆的结点结构 struct Heap { int sta,en; double weight; } heap[5000]; //下滑操作 void siftDown(int start,int end) { //将start号结点向下调整直到end int i=start,j=2*i; heap[0]=heap[i]; //用heap[0]来临时保存i结点的值 while(j<=end) { //有右孩子并且右孩子比左孩子小时,将j保存右孩子 if(j<end&&heap[j].weight>heap[j+1].weight) ++j; //比j号结点小时,不需调整 if(heap[0].weight<=heap[j].weight) break; else { //向下调整 heap[i]=heap[j]; i=j; j=2*j; } } heap[i]=heap[0]; } void siftUp(int start) { int j=start,i=j/2; heap[0]=heap[j]; while(j>0) { if(heap[i].weight<=heap[0].weight) break; else { //向上调整工作 heap[j]=heap[i]; j=i; i=i/2; } } heap[j]=heap[0]; } //插入操作的实现 bool insert(Heap temp) { ++heapNum; heap[heapNum]=temp; siftUp(heapNum); return true; } //删除操作 bool removeMin(Heap& temp) { //保留下根结点 temp=heap[1]; heap[1]=heap[heapNum]; //填补树根 --heapNum; siftDown(1,heapNum); //将根结点下滑到尾部 return true; } /***************************并查集********************/ int parent[101]; //查找i所在的集合的元首,并对该树形结构进行优化 int collaspingFind(int i) { int r=i; for(;parent[r]>=0;r=parent[r]); while(i!=r) { int s=parent[i]; parent[i]=r; i=s; } return r; } void weightedUnion(int i,int j) { int temp=parent[i]+parent[j]; //负数值大的反而小,树i的结点较小时 if(parent[j]<parent[i]) { parent[i]=j; //将i的父亲设为j parent[j]=temp; } else { parent[j]=i; parent[i]=temp; } } /******************************图模块*********************************/ struct LinkNode { int vex; //邻接的结点在数组中的编号 LinkNode* next; double weig; //结点的权值 }; //定义图结点的最大个数 const int MaxSize=101; struct Node { //int data; LinkNode* head; //将结点邻接的链表头置为空 Node(){ head=0;} } Adj[MaxSize]; //Adj数组表示原来的图 //坐标结构体 struct Coord { double x; double y; } coord[101]; //求坐标中两点距离的函数 double sqrtCoord(const Coord& c1,const Coord& c2) { return sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y)); } //建立图的算法 void createLink(int& numNode) { int numLink=0; LinkNode* ptr=0; //赋初值 memset(Adj,0,sizeof(Adj)); for(int i=1;i<=numNode;++i) scanf("%lf%lf",&coord[i].x,&coord[i].y); for(int i=1;i<=numNode;++i) { //头插入建表 for(int j=i+1;j<=numNode;++j) { ptr=new LinkNode; ptr->vex=j; ptr->weig=sqrtCoord(coord[i],coord[j]); ptr->next=Adj[i].head; Adj[i].head=ptr; } } } /**************************最小生成树的模块*****************/ //将图中的所有边存入堆中 void inHeap(int& numNode) { //将堆的结点个数重置为0 heapNum=0; memset(heap,0,sizeof(heap)); LinkNode* ptr=0; for(int v=1;v<=numNode;++v) { ptr=Adj[v].head; //每个邻接点都有机会访问 while(ptr!=0) { //将图中的边和所关联的两个结点压入堆中 Heap temp; temp.sta=v; temp.en=ptr->vex; temp.weight=ptr->weig; insert(temp); ptr=ptr->next; //到下个邻接点 } } } //求出最小生成树的权值之和 void kruskal() { int nodeNum=0; int testNum=1; //程序执行的次数 while(scanf("%d",&nodeNum)!=EOF&&nodeNum!=0) { createLink(nodeNum); //初始化并查集 for(int i=1;i<=nodeNum;++i) parent[i]=-1; //将所有边存入堆中 inHeap(nodeNum); int cntNum=1; double miniLen=0.0; while(cntNum<nodeNum) { Heap temp; //取堆中权值最小的结点 removeMin(temp); int stRoot=collaspingFind(temp.sta); int enRoot=collaspingFind(temp.en); if(stRoot!=enRoot) { weightedUnion(stRoot,enRoot); miniLen+=temp.weight; ++cntNum; } } //要特别注意输出格式!!前几次提交应格式错误告终。。 if(testNum!=1 ) printf( "\n" ); printf( "Case #%d:\n",testNum); printf( "The minimal distance is: %.2lf\n",miniLen); ++testNum; } } int main() { kruskal(); }
相关文章推荐
- ZOJ - 1203 Swordfish (非负权值的最小生成树/最短路 - Kruskal算法)
- ZOJ 1203 Swordfish 剑鱼行动 最小生成树,Kruskal算法
- ZOJ 1203 Swordfish 旗鱼 最小生成树,Kruskal算法
- ZOJ 1203 Swordfish 最小生成树 Kruscal && Prim
- zoj 1203 Swordfish(最小生成树))
- zoj1372----------------Networking 最小生成树 kruskal算法
- Kruskal算法计算最小生成树 C++实现
- Kruskal算法实现最小生成树MST(java)
- java编写Kruskal算法实现最小生成树
- 用于最小生成树的Kruskal算法实现
- Kruskal算法实现最小生成树
- 最小生成树Kruskal算法实现+快排实现权值排序
- 最小生成树,Prim,Kruskal算法主要思想,证明及C++实现
- c++中关于图的最小生成树的Kruskal算法的实现
- 实现Kruskal算法,求图的最小生成树。
- poj1251 Jungle Roads 最小生成树kruskal算法实现
- 用Prim和Kruskal算法实现图的最小生成树
- 最小生成树Kruskal算法实现C++实现
- Kruskal算法求解最小生成树的Java实现
- 最小生成树的Kruskal算法java代码实现