• YCOJ单向公路


    题目:

    描述

     

    某地区有许多城镇,但并不是每个城镇都跟其他城镇有公路连接,并且有的公路并不能双向行驶。现在我们把这些城镇间的公路分布及允许的行驶方向告诉你,你需要编程解决通过公路是否可以从一个城镇到达另一个城镇。(我们规定,城镇自己跟自己可互相到达,即 a 可到达 a)。

    输入

     

    第一行只有一个数 N ,下面将跟着 2N 行数据。

    在前 N 行数据中,每行数据开头第一个数字 number,表明这一行总共有 number个数, number的下一个数为 i ,代表编号为 i 的城镇。这行余下的就是跟 i 有公路连接的城镇名单,并且只能从城镇 i 驶向其他城镇。如 4 1 2 3,表明:此行有 4 个数,跟城镇 1 有公路连接的城镇是编号为 2 和 3 的城镇,且只允许从城镇 1驶向城镇 2 和 3 ,而不能从 2 到 1 或 3 到 1。

    在后 N 行数据中,每行由两个数字组成 a , b。

    对于每个输入的数有如下关系 0≤input_number≤1000。

    输出

     

    对于输入数据中的每个 a,b,判断是否可以从城镇 a 通过公路到达城镇 b,如果可以,输出 Yes;否则输出No。

    输入样例 1 

    3
    4 1 2 3
    3 4 5
    3 5 8
    1 2
    1 8
    4 8

    输出样例 1

    Yes
    No
    Yes


    这是一道经典的搜索题,用BFS或DFS都行,因为博主DFS打的已经很熟了,准备挑战一下自己,所以我就来讲讲BFS的做法。

    如图,因为是单向公路,所以尽管所有点都连得到点2,但点2却一个点都走不到,所以这是一个有向图。


    首先,让我们来定义一波:
    int n;
    queue<int>q;
    vector<int>g[10100];

    这里也就不需要讲了吧,bfs必备的vector和queue的定义也就这样。


    接下来,我们把输入输出解决了,这个输入特别怪异。输入n有2n行,前n行会首先输入一个number,代表这一行加上它共有number个数;后n行每行2个数,是询问,问a和b书否连通。

        cin>>n;
        for (int i=1;i<=n;i++){
            int tmp1,tmp2;
            cin>>tmp1>>tmp2;
            for (int j=1;j<tmp1-1;j++){
                int x;
                cin>>x;
                g[tmp2].push_back(x);
            }
            
        }

    然后进行输出,如果bool类型的bfs值是true或a和b相等,就输出Yes,否则输出No。

        for (int i=1;i<=n;i++){
            int a,b;
            cin>>a>>b;
            if(bfs(a,b)==true||a==b){
                cout<<"Yes"<<endl;
            }
            else {
                cout<<"No"<<endl;
            }
        }

    最后,开始我们的BFS!

    首先,把起点push到队列里。

    bool bfs(int start,int end){
        q.push(start);
    }

    然后开始BFS套路:while (!q.empty())

    接下来,将目前的位置取出来(now),再弹出队列。

    最后,遍历g[now],如果到达了end,就返回ture,否则就将找到的点放在队列里。如果队列都已经清空了,那就只有遗憾地告诉你,没有找到。只有输出No了。

    整个BFS:

    bool bfs(int start,int end){
        
        q.push(start);
        while (!q.empty()){
            int now=q.front();
            q.pop();
            for (int i=0;i<g[now].size();i++){
                if(g[now][i]==end){
                    return true;
                }
                q.push(g[now][i]);
            }
        }
        return false;
    }

    完整代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n,vis[10100];
    queue<int>q;
    vector<int>g[10100];
    
    bool bfs(int start,int end){
        
        q.push(start);
        while (!q.empty()){
            int now=q.front();
            q.pop();
            for (int i=0;i<g[now].size();i++){
                if(g[now][i]==end){
                    return true;
                }
                q.push(g[now][i]);
            }
        }
        return false;
    }
    
    int main(){
        cin>>n;
        for (int i=1;i<=n;i++){
            int tmp1,tmp2;
            cin>>tmp1>>tmp2;
            for (int j=1;j<tmp1-1;j++){
                int x;
                cin>>x;
                g[tmp2].push_back(x);
            }
            
        }
        for (int i=1;i<=n;i++){
            int a,b;
            cin>>a>>b;
            if(bfs(a,b)==true||a==b){
                cout<<"Yes"<<endl;
            }
            else {
                cout<<"No"<<endl;
            }
        }
        return 0;
    }

     最后,Accept送给大家!

  • 相关阅读:
    c++ --> 虚函数
    Algorithm --> 全排列
    Algorithm --> 矩阵链乘法
    STL --> set用法
    STL --> list用法
    Algorithm --> 最长公共子序列(LCS)
    Zookeeper使用实例——服务节点管理
    Zookeeper使用实例——分布式共享锁
    Zookeeper初探
    Java设计模式应用——备忘录模式
  • 原文地址:https://www.cnblogs.com/herobrine-life/p/10959958.html
Copyright © 2020-2023  润新知