POJ 2031

prim算法在这道题上应该是领先Kruskal算法一个数量级的(这道题的是一个稠密图,边的数量为\(V^2\)

比较玄学的是,代码g++ WA, c++ A了,可能是编译器对于浮点数有不同程度的优化吧

另外,在本地做的时候,遇到了一些小bug,解决之后的心得是,循环过程中的初始化阶段很重要

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const double eps= 1e-9;
const double INF= 1e9;
const int maxn= 105;

double x[maxn], y[maxn], z[maxn], r[maxn];
double dis[maxn][maxn];
double lowc[maxn];
int vis[maxn];

inline double Dist(int i, int j)
{
	double ret= sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j]))-r[i]-r[j];

	return ret> eps ? ret : 0;
}

double Prim(const int n)
{
	double ans= 0;
	memset(vis, 0, sizeof(vis));
	vis[1]= 1;
	for (int i= 1; i<= n; ++i){
		lowc[i]= dis[1][i];
	}
	int cnt= n, p;
	double minc= INF;

	while (--cnt){
		minc= INF;
		p= -1;
		for (int i= 1; i<= n; ++i){
			if (!vis[i] && lowc[i]< minc){
				minc= lowc[i];
				p= i;
			}
		}
		if (minc>= INF){
			return -1;
		}
		ans+= minc;
		vis[p]= 1;
		for (int i= 1; i<= n; ++i){
			if (!vis[i] && lowc[i]> dis[p][i]){
				lowc[i]= dis[p][i];
			}
		}
	}

	return ans;
}

int main(int argc, char const *argv[])
{
	int n;
	while (~scanf("%d", &n) && n){
		for (int i= 1; i<= n; ++i){
			scanf("%lf %lf %lf %lf", x+i, y+i, z+i, r+i);
		}
		for (int i= 1; i<= n; ++i){
			for (int j= i+1; j<= n; ++j){
				dis[i][j]= dis[j][i]= Dist(i, j);
			}
			dis[i][i]= 0;
		}
		printf("%.3lf\n", Prim(n));
	}	
	return 0;
}
posted @ 2021-04-12 14:04  IdiotNe  阅读(40)  评论(0)    收藏  举报