/*
问题:平面有若干点,用线段将点连接,使任意两点通过一些列线段相连,给出所有点的坐标,求一种连接方法使所有线段的长度和最小,求该长度和
本质:点为图上的节点,节点之间的线段为边,权值为其长度,求最小生成树之前需要建立图
关键:
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 1000
int 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;
}
机试算法讲解: 第35题 欧拉回路之一笔画
最新推荐文章于 2021-05-24 10:41:31 发布
