您的位置:首页 > 产品设计 > UI/UE

POJ - 2031 Building a Space Station(最小生成树)

2017-08-22 14:33 423 查看
题目链接:http://poj.org/problem?id=2031

题意:给你n个圆的坐标和半径长度,如果两个圆已经相交就不用管它,问还需要多长的长度使得每个圆都相交

思路:枚举每个圆,如果已经相交就把距离改成0,然后kruscal一下就行了

代码:

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <cctype>
#include <sstream>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 5e4 + 5;

int n,p[105],cnt;
struct circular{
double x,y,z,r;
}cir[maxn];
struct edge{
int u,v;
double cost;
}e[maxn];
bool cmp(edge a,edge b){
return a.cost<b.cost;
}
void init (int n) {for (int i=1;i<=n;i++) p[i]=i;}
int Find(int x) {return p[x]==x?x: ( p[x]=Find ( p[x] ) );}
bool same(int a,int b) {return Find(a)==Find(b);}
void unite (int x,int y)
{
x=Find(x);
y=Find(y);
if (x!=y) p[x]=y;
}
double dis(circular a,circular b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z))-a.r-b.r;
}
double kruskal(){
sort(e,e+cnt,cmp);
init(n);
double ans=0;
for (int i=0;i<cnt;i++){
edge ee=e[i];
if (!same(ee.u,ee.v)){
unite(ee.u,ee.v);
ans+=ee.cost;
}
}
return ans;
}
int main () {
//freopen ("in.txt", "r", stdin);
while (~scanf ("%d",&n)&&n){
for (int i=1;i<=n;i++){
double x,y,z,r;
scanf ("%lf%lf%lf%lf",&x,&y,&z,&r);
cir[i].x=x;
cir[i].y=y;
cir[i].z=z;
cir[i].r=r;
}
cnt=0;
for (int i=1;i<=n;i++){
for (int j=i+1;j<=n;j++){
e[cnt].u=i;
e[cnt].v=j;
double q=dis(cir[i],cir[j]);
if (q<0) q=0;
e[cnt++].cost=q;
}
}
printf ("%.3f\n",kruskal());
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: