题目链接
此题是求最小生成树的变形,需要从点和坐标中抽象出边的信息,再利用kruskal求得最小生成树,不过要注意边是否符合要求,不然无法使用。看最后能否构成最小生成树;
**#include <iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
struct edge
{
int a, b;
double cost;
bool operator <(const edge& a)const {
return cost < a.cost;
}
}buf[5000];
struct point {
int x;
int y;
double getdistance(point a) {
double ans = (x - a.x) * (x - a.x) + (y - a.y) * (y - a.y);
return sqrt(ans);
}
}list[105];
int tree[105];
int find(int x)//并查集找根
{
int ret;
int tmp = x;
while (tree[x] != -1) x = tree[x];
ret = x;
x = tmp;
while (tree[x] != -1)
{
int t = tree[x];
tree[x] = ret;
x = t;
}
return ret;
}
int main()
{
int c;
cin >> c;
while (c--)
{
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> list[i].x >> list[i].y;
int size = 0;
for(int i=1;i<=n;i++)
for (int j = i + 1;j <= n;j++)
{
if (list[i].getdistance(list[j]) >= 10 && list[i].getdistance(list[j]) <= 1000)//只取符合要求的边,在这一步提前判断边。
{
buf[size].a = i;
buf[size].b = j;
buf[size].cost = list[i].getdistance(list[j]);
size++;
}
}
sort(buf, buf + size);
for (int i = 1;i <= n;i++) tree[i] = -1;//对数组初始化,每一个都是一个根
double ans = 0;
for (int i = 0;i < size;i++)
{
int a = find(buf[i].a);
int b= find(buf[i].b);
if (a != b) {
ans += buf[i].cost;
tree[a] = b;
}
}
int count = 0;
for (int i = 1;i <= n;i++)
{
if (tree[i] == -1) count++;//通过判断连通分量的个数来确定是否能构成了一个最小生成树。
}
if (count == 1) printf("%.1lf\n", ans * 100);
else cout << "oh!" << endl;
}
return 0;
}**