最小生成树的模板题,prim和kuruskal都可以,但是要注意精度损失。
题意:给定一个三维坐标系,给定一些圆的圆心坐标,和半径,求出所有圆心构成的最小生成树;
特别注意:两个圆如果相交在一起,算做联通,距离为0;
C++提交
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 1e7
using namespace std;
struct node
{
double x,y ,z, r;
}g[100001];
double ma[101][101];
int n;
double SUM(int i,int j)
{
double ju;
ju=sqrt((g[i].x-g[j].x)*(g[i].x-g[j].x)+(g[i].y-g[j].y)*(g[i].y-g[j].y)+(g[i].z-g[j].z)*(g[i].z-g[j].z));
ju = ju - g[i].r - g[j].r;
if(ju>=0)
return ju;
return 0;
}
double sum;
double dis[101],mi;
int pos;
bool vis[101];
void prim()
{
sum=0;
for(int i=0;i<n;i++)
{
dis[i]=ma[0][i];
}
vis[0]=1;
for(int i=0;i<n;i++)
{
pos = 0,mi=INF;
for(int j=0;j<n;j++)
{
if(!vis[j] && mi>dis[j])
{
mi=dis[j];
pos=j;
}
}
if(mi==INF)
return;
sum +=mi;
vis[pos]=1;
for(int j=0;j<n;j++)
{
if(dis[j]>ma[pos][j])
{
dis[j]=ma[pos][j];
}
}
}
}
int main()
{
int i,j;
while(scanf("%d",&n)&&n)
{
memset(ma,0,sizeof(ma));
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&g[i].x,&g[i].y,&g[i].z,&g[i].r);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i!=j)
{
ma[i][j]=SUM(i,j);
}
}
}
sum = 0;
prim();
printf("%.3lf\n",sum);
}
return 0;
}POJ 2031 Building a Space Station(最小生成树),布布扣,bubuko.com
POJ 2031 Building a Space Station(最小生成树)
原文:http://blog.csdn.net/wjw0130/article/details/38317915