机试算法讲解: 第35题 欧拉回路之一笔画

来源:互联网 发布:你好旧时光 知乎 编辑:程序博客网 时间:2024/06/11 02:43
/*问题:平面有若干点,用线段将点连接,使任意两点通过一些列线段相连,给出所有点的坐标,求一种连接方法使所有线段的长度和最小,求该长度和本质:点为图上的节点,节点之间的线段为边,权值为其长度,求最小生成树之前需要建立图关键:1 需要建立点结构体,并且计算任意两点之间的距离,赋予边的结构体,再将边排序,求出最小生成树2 输入的类型必须也是浮点类型,接受取值的也是浮点类型。printf("%d %d\n",&nodeArr[i]._dX,&nodeArr[i]._dY)必须改为printf("%f %f\n",&nodeArr[i]._dX,&nodeArr[i]._dY)3 用sqrt()里面只能放一个计算好的值,不能在里面计算*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define N 1000int Tree[N];typedef struct Edge{int _iV1,_iV2;//一条边的顶点编号double _dWeight;//边上的权值bool operator <= (const Edge& edge){return _dWeight < edge._dWeight;}}Edge;int partition(Edge* edgePtr,int low,int high){Edge ePos = edgePtr[low];while(low < high){while(low < high && ePos <= edgePtr[high]){high--;}edgePtr[low] = edgePtr[high];while(low < high && edgePtr[low] <= ePos){low++;}edgePtr[high] = edgePtr[low];}edgePtr[low] = ePos;return low;}void quickSort(Edge* edgePtr,int low,int high){if(low < high){int iPos = partition(edgePtr,low,high);quickSort(edgePtr,low,iPos-1);quickSort(edgePtr,iPos+1,high);}}int findRoot(int x){if(-1==Tree[x]){return x;}else{int iRoot = findRoot(Tree[x]);Tree[x] = iRoot;return iRoot;}}typedef struct Node{double _dX,_dY;//一个节点的横,纵坐标//获取两点之间的距离double getDistance(const Node& node){double res =  (_dX-node._dX)*(_dX-node._dX) + (_dY-node._dY)*(_dY -node._dY);return sqrt(res);}}Node;int main(int argc,char* argv[]){int iNum,i;while(EOF!=scanf("%d",&iNum)){//获取输入信息//double dX,dY;Edge edgeArr[1000];Node nodeArr[1000];//获取所有点信息        for(i = 0 ; i < iNum ; i++){scanf("%lf %lf",&nodeArr[i]._dX,&nodeArr[i]._dY);//易错,这里输入的类型和必须是%f}//建立边的信息int iSize = 0 ;for(i = 0 ; i < iNum ; i++){for(int j = i + 1 ; j < iNum; j++){//易错,edgeArr[iSize++]._iV1 = i;edgeArr[iSize]._iV1 = i;//edgeArr[iSize++]._iV2 = j;edgeArr[iSize]._iV2 = j;//获取两个结点之间的距离edgeArr[iSize]._dWeight = nodeArr[i].getDistance(nodeArr[j]);iSize++;}}//对边进行快速排序quickSort(edgeArr,0,iSize-1);//易错,对于边,设定每个边的父节点为根结点.这边错误,因为需要将n对顶点之间的每一个顶点的父节点的值设为-1//for(i = 0; i < iSize;i++)//iNum个顶点for(i = 0 ; i < iNum ; i++){Tree[i] = -1;}//对于边,求最小生成树double dWeightSum = 0;for(i = 0 ; i < iSize ; i++){int iRoot1 = findRoot(edgeArr[i]._iV1);int iRoot2 = findRoot(edgeArr[i]._iV2);if(iRoot1!=iRoot2){Tree[iRoot1] = iRoot2;dWeightSum += edgeArr[i]._dWeight;}}printf("%.2f\n",dWeightSum);}system("pause");getchar();return 0;}

0 0
原创粉丝点击