最小生成树
需要把给出的坐标转换成岛与岛之间的距离存储在二维数组中,可以用两个一维数组存储,我用了vector,麻烦了。
数据是有小数的,所以要注意数据类型,我在这里WA了。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#pragma warning(disable:4996)
using namespace std;
const int NN = 100 + 5, INF = 99999999;
double a[NN][NN];
int f[NN];
typedef struct site
{
int x, y;
}site;
int find(int x)
{
if (x == f[x]) return x;
f[x] = find(f[x]);
return f[x];
}
int mer(int x, int y)
{
x = find(x);
y = find(y);
if (x != y)
f[x] = y;
return 1;
}
double dis(site aa, site bb)
{
double x1, y1, x2, y2;
x1 = double(aa.x);
y1 = double(aa.y);
x2 = double(bb.x);
y2 = double(bb.y);
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main()
{
int t, c, x, y, i, j;
double sum;
vector<site> vec;//用了vector存储每个岛的坐标,稍微麻烦了,其实用两个一维数组也就可以了
cin >> t;
while (t--)
{
sum = 0;
vec.clear();
cin >> c;
if (c == 0)
{
cout << "oh!" << endl;
continue;
}
for (i = 0; i < c; i++)
f[i] = i;
for (i = 0; i < c; i++)
{
site s;
scanf("%d %d", &s.x, &s.y);
vec.push_back(s);
}
i = 0;
//将每个岛之间的距离存起来
for (vector<site>::iterator it = vec.begin(); it != vec.end(); it++, i++)
{
j = i + 1;
a[i][i] = INF;
for (vector<site>::iterator jt = it + 1; jt != vec.end(); jt++, j++)
{
double d = dis((*it), (*jt));
if (d < 10 || d > 1000) d = INF;//符合条件的距离存起来,否则距离就是无穷大
a[i][j] = d;
a[j][i] = d;
}
}
while (1)
{
double min0 = INF;//这里我开始用了整形,没有其他错误导致一直找不到WA的原因
int flag = 1;
for(i = 0; i < c; i++)
for (j = 0; j <= i; j++)
if (find(i) != find(j) && a[i][j] < min0)
{
min0 = a[i][j];
x = i;
y = j;
flag = 0;
}
if (flag) break;
mer(x, y);
sum += a[x][y];
}
int p = 0;
for (i = 1; i < c; i++)
if (find(i) != find(i - 1))
{
p = 1;
break;
}
if (p)
printf("oh!\n");
else
printf("%.1lf\n", sum * 100);
}
return 0;
}