一道枚举+搜索题;
很容易看出这道题目要求尽量不在大的城市里面建加油站;
所以从最大的城市开始枚举!
代码:
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #define maxn 130 5 #include<queue> 6 using namespace std; 7 8 struct node 9 { 10 double x,y; 11 } no[maxn]; 12 queue<int>q; 13 int dis[maxn][maxn],n,d,dd[maxn]; 14 bool vis[maxn],flag[maxn]; 15 16 bool bfs() 17 { 18 while(!q.empty())q.pop(); 19 for(int i=1;i<=n;i++)if(flag[i])dd[i]=0; 20 else dd[i]=9999999; 21 q.push(1); 22 vis[1]=1; 23 while(!q.empty()) 24 { 25 int u=q.front(); 26 vis[u]=1; 27 q.pop(); 28 for(int i=1; i<=n; i++) 29 { 30 if(!vis[i]&&i!=u&&dis[u][i]<=d) 31 { 32 dd[i]=min(dd[i],dd[u]+dis[u][i]); 33 if(flag[i])q.push(i); 34 } 35 } 36 } 37 for(int i=1;i<=n;i++) 38 if(flag[i]==0&&dd[i]*2>d)return 0; 39 else if(flag[i]&&!vis[i])return 0; 40 return 1; 41 } 42 43 int main() 44 { 45 while(scanf("%d%d",&n,&d)!=EOF) 46 { 47 memset(flag,1,sizeof flag); 48 memset(vis,0,sizeof vis); 49 for(int i=1; i<=n; i++) 50 scanf("%lf%lf",&no[i].x,&no[i].y); 51 for(int i=1; i<=n; i++) 52 for(int j=i+1; j<=n; j++) 53 dis[i][j]=dis[j][i]=ceil(sqrt((no[i].x-no[j].x)*(no[i].x-no[j].x)+(no[i].y-no[j].y)*(no[i].y-no[j].y))); 54 if(!bfs()){puts("-1");continue;} 55 for(int i=n; i>=2; i--) 56 { 57 memset(vis,0,sizeof vis); 58 flag[i]=0; 59 if(!bfs())flag[i]=1; 60 } 61 int i; 62 for(i=n;i>=1;i--)if(flag[i])break; 63 for(;i>=1;i--)if(flag[i])printf("1"); 64 else printf("0"); 65 printf(" "); 66 } 67 return 0; 68 }