HDU - 1875
题意:n个岛屿,给出Oxy坐标,问让n个岛屿互相连接需要多少钱
思路:最小生成树,先预处理出每个岛屿到其他n-1个岛屿的距离,然后对于这n个点(n-1)*n/2条边用最小生成树算法即可
#include<iostream>
#include<cstdlib>
#include<sstream>
#include<cstdio>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
#define me(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
const int N=2111122;
const int M=300005;
int p[M],n,ct,o;
int dx[10000],dy[10000];
double sum;
struct node {
int l,r;
double ans;
}a[M];
bool cmp(node a,node b) {
return a.ans < b.ans;
}
int find(int root) {
return root==p[root]?root:p[root] = find(p[root]);
}
double dis(int x,int y) {
return sqrt((dx[x]-dx[y])*(dx[x]-dx[y])+(dy[x]-dy[y])*(dy[x]-dy[y]));
}
void kruskal() {
int i;
for(i = 1 ; i <= n ; i++)p[i] = i;
sort(a+1,a+1+o,cmp);
for(i = 1 ; i <= o ; i++) {
int x = find(a[i].l);
int y = find(a[i].r);
if(x != y) {
p[x] = y;
ct ++;
sum += a[i].ans;
if(ct == n-1)break;
}
}
}
int main(void) {
int tt,i,j;
cin >> tt;
while(tt--) {
cin >> n;
o = 0;
sum = 0;
ct = 0;
for(i = 1 ; i <= n ; i++) {
cin >> dx[i] >> dy[i];
}
for(i = 1 ; i <= n ; i++) {
for(j = i+1 ; j <= n ; j++) {
double length = dis(i,j);
if(length>=10&&length<=1000) {
a[++o].l = i;
a[o].r = j;
a[o].ans = length;
}
}
}
kruskal();
sum*=100;
if(ct != n-1) cout << "oh!" << endl;
else printf("%.1f\n",sum);
}
}