问题描述
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。
资源限制
时间限制:1.0s 内存限制:256.0MB
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 int n,m,k; 5 int vis[55],tempvis[55]; 6 double dis[55][55]; 7 double sum=1e9; 8 void dfs(int node,int cnt,double tempsum,double tempdis[55]){ 9 //剩余需要选择的邮局个数超过剩余能选择邮局数,放弃 10 if((k-cnt)>(m-node)) return; 11 //放弃当前邮局,找下一个 12 if((node+1)<m) dfs(node+1,cnt,tempsum,tempdis); 13 double newdis[55]; 14 //复制当前tempdis状态 15 for(int i=0;i<n;i++) 16 newdis[i] = tempdis[i]; 17 //找齐k个邮局,更新最小值tempsum,复制输出最小值时 18 //的临时邮局选择数组tempvis到邮局选择数组vis 19 if(cnt+1==k){ 20 tempvis[cnt]=node; 21 for(int i=0;i<n;i++){ 22 if(newdis[i]>dis[node][i]){ 23 tempsum=tempsum-newdis[i]+dis[node][i]; 24 newdis[i]=dis[node][i]; 25 } 26 } 27 if(tempsum<sum){//更新sum最小值 28 sum=tempsum; 29 for(int i=0;i<k;i++){ 30 vis[i]=tempvis[i]; 31 } 32 } 33 return ; 34 } 35 //选择当前为node的邮局 36 tempvis[cnt]=node; 37 bool not_first=true;//初始化为非挑选的第一个邮局 38 bool useless=true;//初始化为无用邮局 39 if(cnt==0){//cnt==0,必为挑选的第一个邮局 40 for(int i=0;i<n;i++){ 41 tempsum=tempsum+dis[node][i]; 42 newdis[i]=dis[node][i]; 43 } 44 not_first=false;//修正为挑选的第一个邮局 45 }else{//非挑选的第一个邮局 46 for(int i=0;i<n;i++){ 47 if(newdis[i]>dis[node][i]){ 48 tempsum=tempsum-newdis[i]+dis[node][i]; 49 newdis[i]=dis[node][i]; 50 useless=false;//修正为有用邮局 51 } 52 } 53 } 54 //有用邮局或者第一个挑选的邮局都可以进入 55 if(!(not_first&&useless)){ 56 if(node+1<m){//未超过m,选择该邮局,继续挑选下一个邮局 57 dfs(node+1,cnt+1,tempsum,newdis); 58 } 59 } 60 } 61 struct Point{ 62 int x; 63 int y; 64 }; 65 int main(){ 66 cin>>n>>m>>k; 67 double tempdis[55]; 68 Point v[55]; 69 Point p[55]; 70 for(int i=0;i<n;i++){ 71 cin>>v[i].x>>v[i].y; 72 } 73 for(int i=0;i<m;i++){ 74 cin>>p[i].x>>p[i].y; 75 } 76 //计算vi与pj之间的距离disji 77 for(int i=0;i<n;i++){ 78 for(int j=0;j<m;j++){ 79 dis[j][i]=sqrt((v[i].x-p[j].x)*(v[i].x-p[j].x)+(v[i].y-p[j].y)*(v[i].y-p[j].y)); 80 } 81 } 82 83 dfs(0,0,0,tempdis); 84 85 for(int i=0;i<k;i++){ 86 cout<<vis[i]+1<<" "; 87 } 88 cout<<endl; 89 return 0; 90 91 }