HDU 4435

来源:互联网 发布:淘宝上杜蕾斯是真的吗 编辑:程序博客网 时间:2024/05/24 06:50

思路就是贪心,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;}


原创粉丝点击