poj 2031 给出每个结点的3维坐标 以及结点的半径 (MST)

3维空间中有N个圆球,给出x y z 以及圆球的半径 ,求最小生成树 边的权值为两个圆球间的距离 如果圆球相互接触 则权值为0 求最小的权值和

Sample Input

3 //n
10.000 10.000 50.000 10.000 //x y z r
40.000 10.000 50.000 10.000
40.000 40.000 50.000 10.000
2
30.000 30.000 30.000 20.000
40.000 40.000 40.000 20.000
5
5.729 15.143 3.996 25.837
6.013 14.372 4.818 10.671
80.115 63.292 84.477 15.120
64.095 80.924 70.029 14.881
39.472 85.116 71.369 5.553
0
Sample Output

20.000
0.000
73.834

Kruskal

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <cmath>
  6 # define LL long long
  7 using namespace std ;
  8
  9 int n ;
 10 const int MAXN=110;//最大点数
 11 const int MAXM=10000;//最大边数
 12 int F[MAXN];//并查集使用
 13 struct Edge
 14 {
 15     int u,v;
 16     double w ;
 17 }edge[MAXM];//存储边的信息,包括起点/终点/权值
 18
 19 struct poin
 20 {
 21     double x ;
 22     double y ;
 23     double z ;
 24     double r ;
 25 }p[110];
 26
 27 double dist (double dx ,double dy ,double dz , double r1 , double r2)
 28 {
 29     double t =sqrt(dx*dx +dy*dy + dz*dz) ;
 30     if (t > r1 + r2)
 31         return t-r1-r2 ;
 32     else
 33         return 0.0 ;
 34 }
 35
 36 int tol;//边数,加边前赋值为0
 37 void addedge(int u,int v,double w)
 38 {
 39
 40     edge[tol].u=u;
 41     edge[tol].v=v;
 42     edge[tol++].w=w;
 43 }
 44 bool cmp(Edge a,Edge b)
 45 {//排序函数,讲边按照权值从小到大排序
 46     return a.w<b.w;
 47 }
 48 int find(int x)
 49 {
 50     if(F[x]==-1)return x;
 51     else return F[x]=find(F[x]);
 52 }
 53 double Kruskal()//传入点数,返回最小生成树的权值,如果不连通返回-1
 54 {
 55     memset(F,-1,sizeof(F));
 56     sort(edge,edge+tol,cmp);
 57     int cnt=0;//计算加入的边数
 58     double ans=0;
 59     for(int i=0;i<tol;i++)
 60     {
 61         int u=edge[i].u;
 62         int v=edge[i].v;
 63         double w=edge[i].w;
 64         int t1=find(u);
 65         int t2=find(v);
 66         if(t1!=t2)
 67         {
 68             ans+=w;
 69             F[t1]=t2;
 70             cnt++;
 71         }
 72         if(cnt==n-1)break;
 73     }
 74     if(cnt<n-1)return -1;//不连通
 75     else return ans;
 76 }
 77
 78 int main()
 79 {
 80
 81    // freopen("in.txt","r",stdin) ;
 82     while (scanf("%d" , &n) != EOF)
 83     {
 84         if (n == 0)
 85             break ;
 86         int i , j;
 87         double dx , dy , dz ;
 88         for (i=0;i<n;i++)
 89             scanf("%lf%lf%lf%lf" , &p[i].x,&p[i].y,&p[i].z,&p[i].r) ;
 90         tol = 0 ;
 91         for (i = 0 ; i < n ; i++)
 92             for (j = i+1 ; j < n ; j++)
 93             {
 94                 dx = p[i].x - p[j].x ;
 95                 dy = p[i].y - p[j].y ;
 96                 dz = p[i].z - p[j].z ;
 97                 double w = dist(dx,dy,dz,p[i].r,p[j].r) ;
 98                 addedge(i,j,w) ;
 99             }
100         printf("%.3lf\n" ,Kruskal()) ;
101
102     }
103
104     return 0 ;
105 }

时间: 2024-10-06 11:26:55

poj 2031 给出每个结点的3维坐标 以及结点的半径 (MST)的相关文章

Building a Space Station POJ 2031

题目链接: http://poj.org/problem?id=2031 题意:现给定一些细胞的坐标以及它们的半径,求它们彼此联通的最短路径是多少.实则是最小生成树. ////特别心塞,G++提交就错,C++提交就A,害我找错好半天... #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> #include<

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

poj——2031 最小生成树(MST) Kruskal算法

poj——2031 最小生成树(MST)  Kruskal算法 Building a Space Station Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4985   Accepted: 2503 Description You are a member of the space station engineering team, and are assigned a task in the constructio

【华为OJ】【035-输出单向链表中倒数第k个结点】

[华为OJ][算法总篇章] [华为OJ][035-输出单向链表中倒数第k个结点] [工程下载] 题目描述 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针. 输入描述 输入说明 1 输入链表结点个数 2 输入链表的值 3 输入k的值 输出描述 输出一个整数 输入例子 8 1 2 3 4 5 6 7 8 4 输出例子 4 算法实现 import org.omg.SendingContext.RunTime; import java.util.List; import

POJ 2031 prim

Building a Space Station Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 4400 Accepted: 2255 Description You are a member of the space station engineering team, and are assigned a task in the construction process of the station. You are ex

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回

题目:给定一个二叉树其中的一个结点(此节点可以为二叉树任意一个节点),请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 此二叉树的中序遍历为:8.4.9.2.10.5.1.6.3.7 思路: (1)如果此结点有右结点:返回 此结点的右结点 的最左的结点(例如4.2) (2)如果此结点没有右结点:(1)此结点为根节点:返回None  (2)此结点为上一个结点的左节点:返回上一个结点(例如结点6.8)  (3)此结点为上一个结点的右节点:(1)此

剑指Offer(Java版)第六十五题:给定一棵二叉搜索树,请找出其中的第k小的结点。 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

/*给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4.*//*二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值*///思路:从最左边的叶子节点开始找起. import java.util.*; public clas

二叉树中找两个结点的最近的公共祖先结点

#pragma once #include <iostream> using namespace std; /****************  * 二叉树中 找两个结点的最近的公共祖先结点 ******************/ struct Node {     Node* left;     Node* right;     int value;     Node(int v)         :value(v)         ,left(NULL)         ,right(NU

15.输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4260432.html  声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换. 题目分析: