ACdream之使用vector和queue进行邻接表的广搜

B - 娜娜梦游仙境系列——跳远女王

Time Limit:  2000/1000MS (Java/Others)     Memory Limit:  128000/64000KB (Java/Others)
Problem Description

娜娜觉得钢琴很无趣了,就抛弃了钢琴,继续往前走,前面是一片湖,娜娜想到湖的对岸,可惜娜娜找了好久都没找到小桥和小船,娜娜也发现自己不是神仙,不能像八仙过海一样。正当娜娜发愁的时候,娜娜发现湖上面有一些石头!娜娜灵机一动,发现可以沿着石头跳吖跳吖,这样一直跳下去,或许能跳到对岸!

 

娜娜把所有石头的位置都告诉你,然后娜娜能跳的最远距离也是知道的~请聪明的你告诉娜娜,她能够顺利到达对岸吗?

 

为了能够顺利的表达每个石头的位置,假设娜娜正在x轴上,表示湖的一岸,湖的另一岸是直线y=y0,湖中的石头都以有序二元组<x,y>表示,我们可以假设湖是无穷宽,两个石头的距离为几何距离,石头与岸的距离为点到直线的距离。

Input

多组数据,首先是一个正整数t(t<=20)表示数据组数

对于每组数据首先是三个整数y0(1<=y0<=1000),n(0<=n<=1000),d(0<=d<=1000),分别表示湖的另一岸的位置、石头的个数、娜娜一次最远能跳的距离。

接下来是n行,每行是两个整数x,y(0<=|x|<=1000,0<y<y0)

Output

对于每组数据,如果娜娜能够到达湖的另一岸,先输出“YES”,再输出一个整数,表示娜娜最少要跳多少次才能到达另一岸,

如果娜娜不能到达湖的另一岸,先输出“NO”,再输出一个整数,表示娜娜距离湖的另一岸最近的距离。(注意大小写)

Sample Input
2
4 3 1
0 1
0 2
0 3
6 3 2
0 1
1 2
2 3
Sample Output
YES
4
NO
3
Hint

样例一,从x轴->(0,1)->(0,2)->(0,3)->对岸,总共跳4步,输出4

样例二,从x轴->(0,1)->(1,2)->(2,3),此时距离对岸的距离为3,最大跳跃距离为2,无法到达对岸,故输出3

这题一句话不会做,参考月神代码,自己整理了一遍思路,自己敲了一下,

主要就是使用vector容器进行邻接表的储存和使用queue容器进行广搜bfs,

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
struct point
{
    int x,y;
}p[1005];
vector <int> mp[1005];
struct answer
{
    int num,step;
    answer(){}
    answer(int num,int step):num(num),step(step){}
};
int t,yo,n,d;
int ok;
bool dis(point a,point b)
{
    if(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))<=d)
        return 1;
    return 0;
}
int vis[1005];
int bfs()
{
    ok=0;
    int mian=yo;
    queue<answer> qu;
    qu.push(answer(0,0));
    while(!qu.empty())
    {
        answer tmp=qu.front();
        qu.pop();
        mian=min(mian,yo-p[tmp.num].y);
        if(tmp.num==n+1)
        {
            ok=1;
            return tmp.step;
        }
        for(int i=0;i<mp[tmp.num].size();i++)
        {
            if(!vis[mp[tmp.num][i]])
            {
                vis[mp[tmp.num][i]]=1;
                qu.push(answer(mp[tmp.num][i],tmp.step+1));
            }
        }
    }
    return mian;
}
int main()
{
    cin>>t;
    while(t--)
    {

        for(int i=0;i<1005;i++)
            mp[i].clear();
        memset(vis,0,sizeof(vis));
        cin>>yo>>n>>d;
        for(int i=1;i<=n;i++)
            cin>>p[i].x>>p[i].y;
        if(yo<=d)
            mp[0].push_back(n+1);
        for(int i=1;i<=n;i++)
        {
            if(p[i].y<=d)
                mp[0].push_back(i);
            if(yo-p[i].y<=d)
                mp[i].push_back(n+1);
            for(int j=i+1;j<=n;j++)
                if(dis(p[i],p[j]))
                {
                    mp[i].push_back(j);
                    mp[j].push_back(i);
                }
        }
        int tt=bfs();
        if(ok)
            cout<<"YES"<<endl<<tt<<endl;
        else
            cout<<"NO"<<endl<<tt<<endl;
    }
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
邻接表是一种图的存储结构,它可以用于实现图的深度优先索(DFS)和广度优先索(BFS)。下面是邻接表的深广的C语言实现: 1. 邻接表的深度优先索(DFS)C语言实现: ```c #define MAXNODE 1000 #define MAXSIDE 10000 typedef struct SIDE { int tailNode; int nextSide; int weight; } SIDE; SIDE edge[MAXSIDE]; int head[MAXNODE]; int visited[MAXNODE]; int counttEdge = 0; void CreateABoundary(int headNode, int tailNode, int weight) { edge[counttEdge].tailNode = tailNode; edge[counttEdge].weight = weight; edge[counttEdge].nextSide = head[headNode]; head[headNode] = counttEdge; counttEdge++; } void DFS(int node) { visited[node] = 1; printf("%d ", node); for (int i = head[node]; i != -1; i = edge[i].nextSide) { int nextNode = edge[i].tailNode; if (!visited[nextNode]) { DFS(nextNode); } } } int main() { // 初始化 memset(head, -1, sizeof(head)); memset(visited, 0, sizeof(visited)); counttEdge = 0; // 创建图 CreateABoundary(1, 2, 0); CreateABoundary(1, 3, 0); CreateABoundary(2, 4, 0); CreateABoundary(2, 5, 0); CreateABoundary(3, 6, 0); CreateABoundary(3, 7, 0); // DFS遍历 DFS(1); return 0; } ``` 2. 邻接表广度优先索(BFS)C语言实现: ```c #define MAXNODE 1000 #define MAXSIDE 10000 typedef struct SIDE { int tailNode; int nextSide; int weight; } SIDE; SIDE edge[MAXSIDE]; int head[MAXNODE]; int visited[MAXNODE];int counttEdge = 0; void CreateABoundary(int headNode, int tailNode, int weight) { edge[counttEdge].tailNode = tailNode; edge[counttEdge].weight = weight; edge[counttEdge].nextSide = head[headNode]; head[headNode] = counttEdge; counttEdge++; } void BFS(int node) { int queue[MAXNODE]; int front = 0, rear = 0; visited[node] = 1; printf("%d ", node); queue[rear++] = node; while (front < rear) { int curNode = queue[front++]; for (int i = head[curNode]; i != -1; i = edge[i].nextSide) { int nextNode = edge[i].tailNode; if (!visited[nextNode]) { visited[nextNode] = 1; printf("%d ", nextNode); queue[rear++] = nextNode; } } } } int main() { // 初始化 memset(head, -1, sizeof(head)); memset(visited, 0, sizeof(visited)); counttEdge = 0; // 创建图 CreateABoundary(1, 2, 0); CreateABoundary(1, 3, 0); CreateABoundary(2, 4, 0); CreateABoundary(2, 5, 0); CreateABoundary(3, 6, 0); CreateABoundary(3, 7, 0); // BFS遍历 BFS(1); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值