HDU 4435
思路就是贪心,i从n枚举到2,依次判断如果[0,i-1]全设为加油站是否可行,这里用一个bfs即可实现,总复杂度o(n^3)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; int n,d; struct Point{ int x,y; }point[200]; int dis[200][200]; bool vis[200],ok[200]; int dd[200]; void bfs(){ queue<int>q; q.push(1); memset(ok,0,sizeof(ok)); ok[1]=1; for(int i=1;i<=n;i++)dd[i]=1000000; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=1;i<=n;i++){ if(i==u)continue; if(dis[u][i]<=d && ok[i]==0){ if(vis[i]) q.push(i),ok[i]=1; else dd[i]=min(dd[i],dis[u][i]); } } } } void solve(){ int i,j; for(i=1;i<=n;i++) vis[i]=1; for(i=n;i>1;i--){ vis[i]=0; bfs(); bool flag=1; for(j=1;j<=n;j++){ if(vis[j]){ if(ok[j]==0){ flag=0;break; } } else if(dd[j]*2>d){ flag=0;break; } } if(!flag) vis[i]=1; } } int main(){ int i,j; int tem; while(scanf("%d %d",&n,&d)!=EOF){ for(i=1;i<=n;i++) scanf("%d %d",&point[i].x,&point[i].y); bool flag=1; for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) dis[i][j]=dis[j][i]=ceil(sqrt((point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y))); for(i=1;i<=n;i++){ tem=1000000; for(j=1;j<=n;j++){ if(i==j)continue; if(dis[i][j]<tem) tem=dis[i][j]; } if(tem>d) flag=0; } if(flag==0){ printf("-1\n"); continue; } memset(vis,0,sizeof(vis)); solve(); j=n; while(1){ if(vis[j]==0) j--; else break; } for(;j>=1;j--) printf("%d",vis[j]); puts(""); } return 0; }