Problem Description
2100年,科学家们登上月球,在那里建造了很多城镇,并且大部分建在了空中,但还没有铺设道路,无法满足人们的生活需要。为了尽快完成铺设道路任务,他们必须找出一种总路程最短的方案使每个城镇之间都相互可达(并不要求直接可达,通过其它城镇中转也可)。你知道他们方案的总路程数吗?
Input
第一行是一个正整数T,代表数据的组数,每组数据第一行是一个正整数N,代表有N个城镇,接下来N行每行三个正整数xi,yi,zi代表第i个城镇的坐标。
(1<=T<=30,1< N < = 30,0 < = xi,yi,ji < 100)
(1<=T<=30,1< N < = 30,0 < = xi,yi,ji < 100)
Output
使这些城镇畅通的最少总路程数,精确到小数点后两位。
Sample Input
2
2
1 1 0
2 2 0
3
1 2 3
0 0 0
1 1 1
2
1 1 0
2 2 0
3
1 2 3
0 0 0
1 1 1
Sample Output
1.41
3.97
3.97
这题是最小生成树的应用
#include<stdio.h> #include<math.h> typedef struct{ int adj;//记录已构造的生成树的顶点 double lowcost;//某顶点与已构造的部分生成树的顶点之间的最小权值 }closedge; closedge close[31];//辅助数组 int a[31][3];//记录各个点的坐标 double b[31][31];//保存各个点之间的距离 int main() { int t,n,i,j,k; double sum,min; scanf("%d",&t); while(t--) { sum=0;//记录最小生成树的权值之和 scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); for(i=1;i<=n;i++) for(j=1;j<=n;j++) b[i][j]=sqrt((a[i][0]-a[j][0])*(a[i][0]-a[j][0])+(a[i][1]-a[j][1])*(a[i][1]-a[j][1])+(a[i][2]-a[j][2])*(a[i][2]-a[j][2])); for(i=2;i<=n;i++)//辅助数组初始化,这里我先把1这个顶点拉入到最小生成树中 { close[i].adj=1; close[i].lowcost=b[1][i]; } close[1].lowcost=0;//1进入最小生成树,这里设置值为0表示该顶点已经进入生成树,故以后的操作中不需要再考虑它 for(i=1;i<n;i++)//寻找其余的n-1个顶点 { min=10000; for(j=1;j<=n;j++)//找出符合条件的的顶点并记录下来 if(min>close[j].lowcost&&close[j].lowcost!=0) { min=close[j].lowcost; k=j; } sum+=min; close[k].lowcost=0;//k顶点进入最小生成树 for(j=1;j<=n;j++)//新顶点进入之后,修改辅助数组 if(b[k][j]<close[j].lowcost) { close[j].adj=k; close[j].lowcost=b[k][j]; } } printf("%.2lf ",sum); } return 0; }