hdu 4435

来源:互联网 发布:redmine windows 停止 编辑:程序博客网 时间:2024/05/04 23:52

hdu4435

思路:首先费用的特点,前i-1个城市都建的费用<第i个城市的费用,因此采用贪心策略,从n-1,可以不用建加油站的话就不要建;其次如何判断?因为是平面上的点,因此两点间的最短距离就是他们之间的直线距离,因此只要能从1号城市到达每个城市的话就是可行的。因此spfa算出每个点到最近加油站的距离。


#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<queue>#include<set>#include<cmath>#include<ctime>using namespace std;#define eps 1e-8#define N 130#define M 20000200#define ll long long#define inf 0x3f3f3f3f#define mod 1000000007#define MP(a,b) make_pair(a,b)int n,d;double x[N],y[N];int dis[N][N];int ans[N];bool vis[N];int dp[N];int dist(int i,int j){double xx = x[i]-x[j], yy = y[i]-y[j];return ceil(sqrt(xx*xx+yy*yy));}bool check(){queue<int> q;for(int i=0;i<n;i++){if(ans[i]) dp[i] = 0;else dp[i] = inf;vis[i] = false;}q.push(0);vis[0] = true;while(!q.empty()){int u = q.front();q.pop();vis[u] = false;for(int i=0;i<n;i++){if(dp[u]+dis[u][i]<=d){dp[i] = min(dp[i],dis[u][i]);if(ans[i])q.push(i),vis[i] = true;}}}for(int i=0;i<n;i++)if(ans[i]&&!vis[i]||!ans[i]&&2*dp[i]>d) return false;return true;}bool solve(){for(int i=0;i<n;i++)ans[i] = 1;if(!check()) return false;for(int i=n-1;i>0;i--){ans[i] = 0;if(!check()) ans[i] = 1;}return true;}int main(){while(scanf("%d%d",&n,&d)!=EOF){for(int i=0;i<n;i++){scanf("%lf%lf",x+i,y+i);dis[i][i] = inf;for(int j=0;j<i;j++)dis[i][j] = dis[j][i] = dist(i,j);}if(!solve()) puts("-1");else{while(ans[n-1]==0) n--;for(int i=n-1;i>=0;i--)printf("%d",ans[i]);puts("");}}return 0;}


0 0