Arctic Network POJ - 2349 Kruskal

题解

根据题意 需要将所有点联通 但是有M个卫星通信装置 所以可以省去M-1条边
先使用Kruskal跑最小生成树 再减去M-1条较大边剩下的取最大为答案

AC代码

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const double EPS = 1e-6;
const int MAXN = 5e2 + 10;
int M, N;
int vex[MAXN];

struct node
{
	int x, y;
}a[MAXN];
struct edge
{
	int u, v;
	double w;
	edge(int a, int b, double c) : u(a), v(b), w(c){}
	bool operator < (const edge &oth) const
	{
		return w < oth.w;
	}
};
vector<edge> ed;
double dis(int x1, int y1, int x2, int y2)
{
	return sqrt((x1 - x2) * (x1 - x2) * 1.0 + (y1 - y2) * (y1 - y2) * 1.0);
}
int findr(int x)
{
	return vex[x] == x ? x : vex[x] = findr(vex[x]);
}
void join(int x, int y)
{
	int yy = findr(y);
	int xx = findr(x);
	vex[yy] = xx;
}
double kru()
{
	for (int i = 0; i < N; i++)
		vex[i] = i;
	vector<double> vec;
	for (int i = 0; i < ed.size(); i++)
		if (findr(ed[i].u) != findr(ed[i].v))
		{
			join(ed[i].u, ed[i].v);
			vec.push_back(ed[i].w);
		}
	double ans = 0;
	for (int i = 0; i < vec.size() - M + 1; i++) //减去M-1条较长边
		ans = max(ans, vec[i]);
	return ans;
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int T;
	cin >> T;
	while (T--)
	{
		cin >> M >> N;
		for (int i = 0; i < N; i++)
			scanf("%d%d", &a[i].x, &a[i].y);
		ed.clear();
		for (int i = 0; i < N; i++)
			for (int j = i + 1; j < N; j++)
				ed.push_back(edge(i, j, dis(a[i].x, a[i].y, a[j].x, a[j].y)));
		sort(ed.begin(), ed.end());
		printf("%.2lf\n", kru());
	}

	return 0;
}

你可能感兴趣的:(___图论___,kruskal)