POJ 2627 Gopher and hawks(bfs)

125 篇文章 0 订阅

Description
一只地鼠想从起始坑(x1,y1)跑到终点坑(x2,y2),其速度为v m/s,可是如果它在路上跑了m分钟那么它就会被老鹰吃掉,所以它要借助一些其他的坑来躲避老鹰,现给出这些坑的坐标,问地鼠最少经过几个坑能够到达终点,如果地鼠一定被吃掉则输出No.
Input
第一行为两个整数v和m分别表示地鼠速度和待在地面上的最长时间,之后两行每行两个浮点数分别表示起点和终点坐标,最后输入多个坑的坐标,以文件尾结束输入,坑的数量不超过1000个
Output
如果地鼠能够在不被老鹰吃掉的情况下跑到终点则输出经过的最少坑数,否则输出No.
Sample Input
3 1
0.000 0.000
500.000 0.000
179.000 0.000
358.000 0.000
Sample Output
Yes, visiting 2 other holes.
Solution
设坑有n个,将起点和终点看作第0个坑和第n+1个坑,如果两坑之间距离不大于v*m*60则在这两个坑之间建边,那么问题转化为从0到n+1的最短路问题,因为此处边权均为1所以直接用bfs即可求解
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define maxn 1111
#define INF 0x3f3f3f3f
struct Edge
{
    int to,next;
}edge[maxn*maxn];
int head[maxn],tot,n=1,vis[maxn],dis[maxn];
struct node
{
    double x,y;
}s,e,p[maxn];
void add(int u,int v)
{
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
double get_dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int bfs()
{
    queue<int>que;
    que.push(0);
    dis[0]=0,vis[0]=1;
    for(int i=1;i<=n;i++)
        dis[i]=INF,vis[i]=0;
    while(!que.empty())
    {
        int u=que.front();que.pop();
        for(int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(!vis[v])
            {
                que.push(v);
                vis[v]=1;
                dis[v]=dis[u]+1;
            }
        }
    }
    return dis[n];
}
int main()
{
    memset(head,-1,sizeof(head));
    tot=0;
    double v,m,d;
    scanf("%lf%lf%lf%lf%lf%lf",&v,&m,&s.x,&s.y,&e.x,&e.y);
    d=v*m*60;
    p[0]=s;
    while(~scanf("%lf%lf",&p[n].x,&p[n].y))n++;
    p[n]=e;
    for(int i=0;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(get_dis(p[i],p[j])<=d)
                add(i,j),add(j,i);
    int ans=bfs();
    if(ans==INF)printf("No.\n");
    else printf("Yes, visiting %d other holes.\n",ans-1);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值