原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1875
其实这题很简单,但是当时脑子不知道怎么了,两点不连通我把它表示成-1标记,而不是直接赋值为最大值,导致接下来的操作有点混乱。
代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
double x[105], y[105];
double a[105][105];
double lowCost[105];
int T;
int C;
int num;//标记是否是所有点都加入到生成树中
double getDis(int i, int j)
{
return sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]));
}
double prim()
{
double ans = 0;
num = 1;//起点默认是加入的,所以是1
for (int i = 1; i <= C; i++)
lowCost[i] = a[1][i];//默认1为起点
lowCost[1] = 0;//标记起点已被加入生成树
for (int i = 1; i < C; i++)
{
double min = 99999999;
int minIndex;
for (int i = 1; i <= C; i++)
{
if (lowCost[i] != 0 && lowCost[i] != -1 && lowCost[i] < min)
{
min = lowCost[i];
minIndex = i;
}
}
if (min == 99999999)//如果无法构成所有节点的生成树,就会提前结束
return ans;
num++;//又加入一个
ans += min;
lowCost[minIndex] = 0;
for (int i = 1; i <= C; i++)
{
if (lowCost[i] != 0 && a[minIndex][i] != -1 && a[minIndex][i] < lowCost[i] || lowCost[i] == -1)
lowCost[i] = a[minIndex][i];
}
}
return ans;
}
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &C);
for (int i = 1; i <= C; i++)
scanf("%lf%lf", &x[i], &y[i]);
if (C <= 1)
printf("oh!\n");
else
{
for (int i = 1; i <= C; i++)
{
for (int j = 1; j <= C; j++)
{
double dis = getDis(i, j);
if (dis < 10 || dis>1000)
a[i][j] = -1;//-1表示该点不通
else
a[i][j] = dis;
}
}
double ans = prim();
if (num != C)
printf("oh!\n");
else
printf("%.1lf\n", ans * 100);
}
}
return 0;
}