[每日一题]:村庄建设

题目:

考察点:

最小生成树、prim算法

Code:

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

#define INF 0x3f3f3f3f

using namespace std;

typedef long long LL;

typedef pair<int,int>PII;

const int maxn = 1005;

double graph[maxn][maxn],dist[maxn];

int vis[maxn];

double sum = 0;

struct node {
	int x,y,h;
}p[maxn];

int n;


void init() {
	for(int i = 0; i <= n; i ++) {
		for(int j = 0; j <= n; j ++) {
			graph[i][j] = INF;
		}
		dist[i] = INF;
	}
	return ;
}

double prim() {
    dist[1] = 0;
    for(int i = 1; i <= n; i ++) {
        int cur = -1;
        for(int j = 1; j <= n; j ++) {
            if(!vis[j] && (cur == -1 || dist[j] < dist[cur])) {
                cur = j;
            }
        }
        
        sum += dist[cur];
        vis[cur] = 1;
        for(int j = 1; j <= n; j ++){
            dist[j] = min(dist[j],graph[cur][j]);
        }
    } 
    return sum;
}

int main(void) {
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].h);
	}
	init();
	for(int i = 1; i < n; i ++) {
		for(int j = i + 1; j <= n; j ++) {
			double value = sqrt( (p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y-p[j].y) * (p[i].y-p[j].y)) + (p[i].h-p[j].h) * (p[i].h-p[j].h);
			graph[i][j] = graph[j][i] = min(graph[i][j],value);
		}
	}
	printf("%.2lf\n",prim());
	return 0;
} 
posted @ 2020-04-19 22:18  IceSwords  阅读(129)  评论(0编辑  收藏  举报