试题 历届试题
问题描述
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
想法:
痛苦深搜,这就是新时代的体罚,超出我的想象范围,虽然有可能是我过于弱智所导致的,但是确实是我的问题,我真的已经尽力了,为什么,最后一个点就是搞不定,世界已经崩塌了。(scanf还是顶啊)
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct man{
double x,y;
}ma[60];
int n,m,d,dd[60],book[60],max1=999999999,qq[60];
double dp[30][60];
void dfs(int node,int k){
if(node==d){
double num=0,bfs[60];
for(int i=0;i<node;i++){
for(int j=0;j<n;j++){
if(i==0)bfs[j]=dp[dd[i]][j];
else bfs[j]=min(bfs[j],dp[dd[i]][j]);
}
}
for(int j=0;j<n;j++){
num+=bfs[j];
}
if(num<max1){
max1=num;
for(int i=0;i<node;i++){
qq[i]=dd[i];
}
}
return;
}
for(int i=k;i<=m;i++){
if(!book[i]){
book[i]=1;
dd[node]=i;
dfs(node+1,i);
book[i]=0;
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&d);
for(int i=0;i<n;i++){
scanf("%lf%lf",&ma[i].x,&ma[i].y);
}
for(int i=1;i<=m;i++){
double q,p;
scanf("%lf%lf",&q,&p);
for(int j=0;j<n;j++){
dp[i][j]=sqrt((q-ma[j].x)*(q-ma[j].x)+(p-ma[j].y)*(p-ma[j].y));
}
}
dfs(0,1);
for(int i=0;i<d;i++){
if(i!=0)printf(" ");
printf("%d",qq[i]);
}
printf("\n");
return 0;
}