HOJ 1875 畅通工程再续

最小生成树
需要把给出的坐标转换成岛与岛之间的距离存储在二维数组中,可以用两个一维数组存储,我用了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;
}

猜你喜欢

转载自blog.csdn.net/qq_44724908/article/details/104183171