藍橋杯歷屆試題 郵局(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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章