【C - Building a Space Station】

本文介绍了一种使用PRIM算法求解最小生成树(MST)的方法,通过邻接矩阵存储图,并详细展示了如何利用优先队列进行松弛操作,最终实现高效计算。代码示例展示了如何初始化、添加单元格、计算距离以及执行PRIM算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

  • 最小生成树PRIM
  • 存储所有点,邻接矩阵存图。
  • 除了松弛没什么特殊的了。

代码:

  • 188ms 1028kB
//188ms		1028kB


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cmath>
#define MAXV 1e5

using namespace std;

const int maxn = 105;

int N;
double ans;
bool vis[maxn];
double dis[maxn];
double mp[maxn][maxn];
struct CELL{
	double x,y,z,r;
}cell[maxn];
void ADDCELL(int i,double x,double y,double z,double r){
	cell[i].x = x;
	cell[i].y = y;
	cell[i].z = z;
	cell[i].r = r;
	return ;
}
struct NODE{
	int id;
	double dis;
	NODE(int id,double dis) : id(id) , dis(dis) {} ;
	friend bool operator > (NODE a , NODE b){
		return a.dis > b.dis ; 
	}
};
priority_queue <NODE , vector<NODE> , greater<NODE> > Q;

void INIT(){
	ans = 0;
	memset(vis , 0 , sizeof(vis));
	for(int i=1;i<=N;i++)
		dis[i] = MAXV;
	return ;
}

void PRIM(){
	dis[1] = 0;
	Q.push(NODE(1 , 0));
	while(Q.size()){
		NODE cur = Q.top() ; Q.pop() ;
		int id = cur.id ;
		if(vis[id])
			continue;
		vis[id] = true;
		ans += dis[id];
		for(int i=1;i<=N;i++){
			if(id == i)
				continue;
			if((cell[id].r + cell[i].r) > sqrt(mp[id][i])){
				dis[i] = 0;
				Q.push(NODE(i , 0));
				continue;
			}
			if(dis[i] > sqrt(mp[id][i]) - cell[id].r - cell[i].r){
				dis[i] = sqrt(mp[id][i]) - cell[id].r - cell[i].r;
				Q.push(NODE(i , dis[i]));
			}
		} 
	}
	return ;
}

int main(){
	while(cin>>N && N){
		INIT();
		for(int i=1;i<=N;i++){
			double x,y,z,r;
			cin>>x>>y>>z>>r;
			ADDCELL(i,x,y,z,r);
		}
		for(int i=1;i<=N;i++){
			double xi = cell[i].x;
			double yi = cell[i].y;
			double zi = cell[i].z;
			for(int j=i;j<=N;j++){
				double xj = cell[j].x;
				double yj = cell[j].y;
				double zj = cell[j].z;
				mp[i][j] = mp[j][i] = (xi-xj)*(xi-xj) + (yi-yj)*(yi-yj) + (zi-zj)*(zi-zj) ;
			}
			mp[i][i] = 0;
		}
		PRIM();
		printf("%.3f\n" , ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值