蓝桥杯历届试题 邮局(DFS)

问题描述   C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。

  现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。 输入格式   输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。

  接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。

  接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。

  在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。 输出格式   输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号) 样例输入 5 4 2

0 0

2 0

3 1

3 3

1 1

0 1

1 0

2 1

3 2 样例输出 2 4 数据规模和约定

  对于30%的数据,1<=n<=10,1<=m<=10,1<=k<=5;
  对于60%的数据,1<=m<=20;
  对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。

最后两组数据超时。

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n, m, k,ans[16],cm[56][2];
float d[51][26],sum = 1e9;
void dfs( int choice,int cur, float w[51],int a[16])
{
	if (choice == k)
	{
		float su=0;
		for (int i = 1;i<=n;i++)
			su += w[i];
		if(sum>su)
		sum = su,
		memcpy(ans, a, sizeof(ans));
		return;
	}
	int i = cur + 1;
	if (i <= m&&k - choice <= 1 + m - i)
	{
		int ok = 0;
		float t[51];
		memcpy(t, w, sizeof(t));
		a[choice+1] = i;
		for (int j = 1;j <= n;j++)
			if (w[j] > d[j][i])
				w[j] = d[j][i],ok=1;
		if (ok)
			dfs(choice + 1, i, w, a);
		dfs(choice, i, t, a);
	}
}
int main()
{
	float w[51];
	int a[16];
	cin >> n >> m >> k;
	for (int i = 1;i <= n;i++)
		w[i] = 1e9;
	for (int i = 1;i <= n;i++)
		cin >> cm[i][0] >> cm[i][1];
	for (int j = 1;j <= m;j++)
	{
		int x, y;
		cin >> x >> y;
		for (int i = 1;i <= n;i++)
			d[i][j] = sqrt((x - cm[i][0])*(x - cm[i][0]) + (y - cm[i][1])*(y - cm[i][1]));
	}
	dfs(0, 0, w, a);
	for (int i = 1;i <= k;i++)
		cout << ans[i] << ' ';
	return 0;
}

    原文作者:DFS
    原文地址: https://blog.csdn.net/qq_33245342/article/details/55272320
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞