BFS:边权相同的最短路问题

news2024/9/23 1:29:43

一、边权相同最短路问题简介

二、迷宫中离入口最近的出口

. - 力扣(LeetCode)

class Solution {
public:
    const int dx[4]={1,-1,0,0};
    const int dy[4]={0,0,1,-1};
    int nearestExit(vector<vector<char>>& maze, vector<int>& e) {
      int m=maze.size(),n=maze[0].size();
      queue<pair<int,int>> q;//队列
      bool check[m][n]; //非全局的bool是乱值 全局的会初始化为0
      //力扣支持这样的写法
      memset(check,0,sizeof(check)); //初始化成0
      q.emplace(e[0],e[1]);
      check[e[0]][e[1]]=true;
      int step=0;//统计步数
      while(!q.empty())
      {
         ++step;
         //要控制同一层出
         int sz=q.size();
         for(int i=0;i<sz;++i)
           {
            auto[a,b]=q.front();
            q.pop();
            for(int k=0;k<4;++k)
            {
                int x=dx[k]+a,y=dy[k]+b;
                if(x>=0&&x<m&&y>=0&&y<n&&maze[x][y]=='.'&&check[x][y]==false)
                {
                    //如果找到最后一个了,就可以直接返回了
                    if(x==0||x==m-1||y==0||y==n-1) return step;
                    //如果没找到,继续进
                    q.emplace(x,y);
                    check[x][y]=true;
                }
            }
           }
      }
      return -1;
    }
};

三、最小基因变化(经典图论bfs)

. - 力扣(LeetCode)

class Solution {
public:
//转化成图论中的bfs问题
    int minMutation(string startGene, string endGene, vector<string>& bank) {
       if(startGene==endGene) return 0;
       string s("AGCT");//四种变化情况
       unordered_set<string> hash1(bank.begin(),bank.end());//负责帮助我们快速查找字符串是否在基因库中
       if(hash1.count(endGene)==0) return -1;
       queue<string> q;//存储在基因库中出现过的变化后字符串
       q.emplace(startGene);
       unordered_set<string> hash2;//负责标记哪些字符串被搜索过
       hash2.insert(startGene);
       int step=0;//用来统计步数
       while(!q.empty())
       {
        ++step;
        int sz=q.size();//控制一行一行出
        for(int i=0;i<sz;++i)
        {
            string temp=q.front();//待处理的字符串
            q.pop();
            for(int j=0;j<8;++j) //遍历字符串的每个位置
            {
                for(int k=0;k<4;++k)
                {
                    string cur=temp;
                    cur[j]=s[k];//修改
                    if(hash1.count(cur)&&hash2.count(cur)==0)//如果基因库找到了 就丢进去
                    {
                        if(cur==endGene) return step;
                        hash2.insert(cur);
                        q.emplace(cur);
                    }
                }
            } 
        }
       }
       return -1;
    }
};

 四、单词接龙

. - 力扣(LeetCode)

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        int n=beginWord.size();
        //需要一个哈希表存储字典中的字符串,方便快速搜索是否存在
        unordered_set<string> hash(wordList.begin(),wordList.end());
        //需要一个标记哈希表帮助我们判断被搜索过的字符串 
        if(!hash.count(endWord)) return 0;
        unordered_set<string> vis;
        queue<string> q;
        vis.insert(beginWord);
        q.emplace(beginWord);
        int ret=1;
        while(!q.empty())
        {
            ++ret;
            //要控制一行一行出
            int sz=q.size();
            for(int i=0;i<sz;++i)
            {
                string t=q.front();
                q.pop();
                //开始想办法修改
                for(int j=0;j<n;++j) //遍历字符串的每个位置
                    for(char k='a';k<='z';++k)
                    {
                    string temp=t;
                    temp[j]=k;//修改
                    //如果修改后在字典中找到,就可以加入队列中 如果是最终结果就返回
                    if(hash.count(temp)&&!vis.count(temp))
                    {
                        if(temp==endWord) return ret;
                        vis.insert(temp);
                        q.emplace(temp);
                    }
                    }
            }
        }
        return 0;
    }
};

五、为高尔夫比赛砍树(经典bfs)

. - 力扣(LeetCode)

        转化成多个最短路问题,但是我们需要知道从哪树开始砍,第一个方法就是用map进行存储,可以顺便帮助我们排序,第二个方法就是用vector进行存储,然后sort+lambda表达式解决问题 

策略1:用map

class Solution {
public:
    typedef pair<int,int> PII;
    int m,n;
    const int dx[4]={1,-1,0,0};
    const int dy[4]={0,0,1,-1};
    int cutOffTree(vector<vector<int>>& f) {
     //转化成若干个迷宫问题
     //得存下标和值 并且要方便排序
     m=f.size(),n=f[0].size();
     map<int,PII> hash;//前面存值 后面存下标
     for(int i=0;i<m;++i)
      for(int j=0;j<n;++j)
       if(f[i][j]>1) hash[f[i][j]]=make_pair(i,j); //map会帮助我们排好序
        //然后按顺序砍树
        int bx=0,by=0; //初始位置
        int ret=0;
        for(auto&it:hash)
        {
            auto&[a,b]=it.second;
            int step=bfs(f,bx,by,a,b);
            if(step==-1) return -1;
            ret+=step;
            //往下迭代 
            bx=a,by=b;
        }
        return ret;
    }
    bool vis[50][50];
    int bfs(vector<vector<int>>& f,int bx,int by,int a,int b)
    { 
        //转化成迷宫问题  从起点到终点的最短路问题
        if(bx==a&&by==b) return 0; //有可能直接从起始位置开始砍
        queue<PII> q;
       //必须要清空之前的数据
        memset(vis,0,sizeof(vis));
        q.emplace(bx,by);
        vis[bx][by]=true;
        int step=0;
        while(!q.empty())
        {
          //要控制一层一层走
           ++step;
           int sz=q.size();
           for(int i=0;i<sz;++i)
           {
             auto[ex,ey] =q.front();
             q.pop();
             for(int k=0;k<4;++k)
             {
                int x=dx[k]+ex,y=dy[k]+ey;
                if(x>=0&&x<m&&y>=0&&y<n&&f[x][y]!=0&&vis[x][y]==false)
                 {
                    if(x==a&&y==b) return step;
                    //丢进去
                    q.emplace(x,y);
                    vis[x][y]=true;
                 }
             }
           }
        }
        return -1;
    }
};

策略2:vector+sort+lambda

class Solution {
public:
    typedef pair<int,int> PII;
    int m,n;
    const int dx[4]={1,-1,0,0};
    const int dy[4]={0,0,1,-1};
    int cutOffTree(vector<vector<int>>& f) {
     //转化成若干个迷宫问题 关键就在于我们怎么确定砍树的顺序
     //得存下标和值 并且要方便排序
     m=f.size(),n=f[0].size();
   //用一个vector存储下标,然后排序的时候用lambda表达式
     vector<PII> trees;
     for(int i=0;i<m;++i)
      for(int j=0;j<n;++j)
       if(f[i][j]>1) trees.emplace_back(i,j); 
  //sort+lambda 进行排序
    sort(trees.begin(),trees.end(),[&f](const PII&kv1,const PII&kv2) //lambda捕获f
    {
        return f[kv1.first][kv1.second]<f[kv2.first][kv2.second];
    });

        //然后按顺序砍树
        int bx=0,by=0; //初始位置
        int ret=0;
        for(auto&[a,b]:trees)
        {
            int step=bfs(f,bx,by,a,b);
            if(step==-1) return -1;//说明无路可走了
            ret+=step;
            //往下迭代 
            bx=a,by=b;
        }
        return ret;
    }
    bool vis[50][50];
    int bfs(vector<vector<int>>& f,int bx,int by,int a,int b)
    { 
        //转化成迷宫问题  从起点到终点的最短路问题
        if(bx==a&&by==b) return 0; //有可能直接从起始位置开始砍
        queue<PII> q;
       //必须要清空之前的数据 
        memset(vis,0,sizeof(vis));
        //如果不定义成全局的标记数据的话, 也可以定义成局部的标记数组,但同样需要进行初始化
        q.emplace(bx,by);
        vis[bx][by]=true;
        int step=0;
        while(!q.empty())
        {
          //要控制一层一层走
           ++step;
           int sz=q.size();
           for(int i=0;i<sz;++i)
           {
             auto[ex,ey] =q.front();
             q.pop();
             for(int k=0;k<4;++k)
             {
                int x=dx[k]+ex,y=dy[k]+ey;
                if(x>=0&&x<m&&y>=0&&y<n&&f[x][y]!=0&&vis[x][y]==false)
                 {
                    if(x==a&&y==b) return step;
                    //丢进去
                    q.emplace(x,y);
                    vis[x][y]=true;
                 }
             }
           }
        }
        return -1;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1907709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

思路打开!腾讯造了10亿个角色,驱动数据合成!7B模型效果打爆了

世界由形形色色的角色构成&#xff0c;每个角色都拥有独特的知识、经验、兴趣、个性和职业&#xff0c;他们共同制造了丰富多元的知识与文化。 所谓术业有专攻&#xff0c;比如AI科学家专注于构建LLMs,医务工作者们共建庞大的医学知识库&#xff0c;数学家们则偏爱数学公式与定…

p11函数和递归

递归与迭代 求n的阶乘。&#xff08;不考虑溢出&#xff09; int Fac1(int n) {int i0;int ret1;for(i1;i<n;i){ret*i;}return ret; } int main(){//求n的阶乘int n0;int ret0;scanf("%d",&n);retFac1(n);printf("%d\n",ret);return 0; } int Fac…

一.2.(5)共射、共集、共基三种基本放大电路的静态及动态分析;

共什么的问题&#xff1a;共什么取决于输入输出&#xff0c;共剩下的那一极 1.基本共射放大电路 见前面章节&#xff0c;不做累述 2.基本共集放大电路 列KVL方程&#xff0c;求解 AU1&#xff0c;所以又叫射极跟随器 Ib是流入基极的电流&#xff0c;Ii是从输入交流信号源流出的…

昇思25天学习打卡营第11天|文本解码原理-以MindNLP为例

文本解码原理-以MindNLP为例 这篇主要讲讲文本生成的几个方法&#xff0c;首先介绍一下什么是自回归语言模型。 自回归语言模型 autoregressive language model&#xff0c;根据前面的词或上下文&#xff0c;生成后续的词或句子的语言模型。 有几种典型的自回归语言模型&…

python爬虫入门(三)之HTML网页结构

一、什么是HTML 1、网页的三大技术要素&#xff1a; HTML定义网页的结构和信息&#xff08;骨架血肉&#xff09;CSS定义网页的样式&#xff08;衣服&#xff09;JavaScript定义用户和网页的交互逻辑&#xff08;动作&#xff09; 2、一个最简单的HTML&#xff1a;用<>…

动态数据库设计

动态数据库设计是一种灵活的方法&#xff0c;用于构建能够适应不断变化的数据需求的数据库结构。它强调在不频繁修改数据库表结构的前提下&#xff0c;有效管理和存储多样化的数据。以下是实现动态数据库设计的一些关键技术点和策略&#xff1a; 实体-属性-值&#xff08;EAV&a…

意得辑ABSJU202优惠15%啦,新用户注册直减哦

不得不说&#xff0c;还得是意得辑&#xff0c;钱不白花&#xff0c;润色的挺好~ 第一篇SCI终于成功见刊&#xff01;&#xff01;&#xff01; 都来接accept&#xff01;&#xff01;&#xff01;谢谢accept小狗&#xff0c;接accept 求求accept小狗&#xff0c;真的想要双证毕…

OpenLayers对要素进行新增绘制、选择、修改等交互操作

1、绘制-Draw 新建一个用来绘制要素的图层&#xff1a; const vector new VectorLayer({source: new VectorSource(),style: {"fill-color": "rgba(255, 255, 255, 0.2)","stroke-color": "#ffcc33","stroke-width": 2,&q…

如何提升美国Facebook直播的整体体验?

Facebook作为全球最大的社交媒体平台之一&#xff0c;提供了直播功能&#xff0c;用户可以实时分享生活、见解和创意。许多商家通过美国Facebook直播来获取更多客户&#xff0c;但直播时可能会遇到网络卡顿的问题&#xff0c;导致观看体验不佳。本文将探讨如何解决这个问题&…

Ubuntu开源软件LibreOffice将Excel多表转PDF多目录示例

一、实现的起因&#xff1a; Windows平台下&#xff0c;常见的WPS办公自动化套件中电子表格软件&#xff0c;其中具备将Excel工作表中数据转为PDF文档表格的功能。现在进一步的需求是&#xff1a;像PDF标准的电子书那样&#xff0c;具备一本书的目录结构或章节结构&#xff0c…

[C++]入门基础(1)

Hello大家好&#xff0c;今天通过本篇文章&#xff0c;我们来初步学习C&#xff0c;C可以说是对C语言的一个升级&#xff0c;我们会一步一步的由浅入深的学习C。 目录 1.第一个C程序 2.命名空间 2.1 命名空间出现的意义 2.2 namespace的定义 2.3 命名空间的使用 3.C输入…

Spring Cloud - 代码生成器

1、代码生成器概述 Spring Cloud 并没有提供类似于 Spring Data 中的“代码生成器”&#xff0c;因为它主要提供的是分布式系统中服务发现和配置管理的一套解决方案。如果你想要为你的微服务应用生成样板代码&#xff0c;你可能需要考虑使用其他工具或者方案&#xff0c;例如 S…

基于SSM的志愿者服务平台

基于SSM的志愿者服务平台系统主要其系统包括不同的端组成&#xff0c;前端主要包括系统用户管理、新闻数据管理、变幻图管理、志愿者管理、培训视频管理、志愿者项目管理、服务时长管理、交流分享管理、志愿者表彰管理。前台主要包括网站首页、培训视频、志愿者项目、交流分享、…

【python中级】图像从笛卡尔坐标系转换为极坐标系

【python中级】图像从笛卡尔坐标系转换为极坐标系 1.背景2.生成二维图3.极坐标转换1.背景 笛卡尔坐标系就是我们常说的直角坐标系。 笛卡尔坐标系,也称为直角坐标系,是由法国数学家和哲学家勒内笛卡尔(Ren Descartes)发明的一种二维或三维坐标系统。它使用两个或三个相互垂…

李彦宏: 开源模型是智商税|马斯克: OpenAI 闭源不如叫 CloseAI

在 2024 年世界人工智能大会&#xff08;WAIC 2024&#xff09;上&#xff0c;百度创始人、董事长兼首席执行官李彦宏发表对开源模型的评价。 李彦宏认为&#xff1a;开源模型实际上是一种智商税&#xff0c;而闭源模型才是人工智能&#xff08;AI&#xff09;行业的未来。 马…

基于LangChain的RAG开发教程(二)

v1.0官方文档&#xff1a;https://python.langchain.com/v0.1/docs/get_started/introduction/ 最新文档&#xff1a;https://python.langchain.com/v0.2/docs/introduction/ LangChain是一个能够利用大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;能…

git恢复到之前提交的记录

项目搞崩了&#xff0c;还提交上去了怎么办&#xff1f; 那当然是恢复到之前的提交记录了&#xff0c;那怎么操作呢&#xff1f; 首先&#xff0c;到代码托管平台找到你想恢复的提交记录(在此以github为例) 获取 commit id 首先&#xff0c;通过如下图操作获取到commit id {% a…

Spring Cloud: OpenFeign 超时重试机制

超时重试是一种用于网络通信的常用策略&#xff0c;目的是在请求未能在规定时间内获得响应或响应超时的情况下&#xff0c;重新发送请求。具体来说&#xff0c;当发起请求后&#xff0c;如果在设定的时间内未能收到预期的响应&#xff0c;就会启动超时重试机制&#xff0c;重新…

徒手绘制 Android 通用进度条

拖动条&#xff08;FlexSeekBar&#xff09;&#xff0c;在Android的各个地方都非常常用&#xff0c;本文旨在自研一套通用的进度条&#xff0c;非常适合车载App使用 样式如下&#xff1a; 使用示例 <!--默认用法--> <com.max.android.ui.seekbar.FlexSeekBarandroi…

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序 1、流程 1、获取文件绝对路径下的所有文件 2、通过os.path.getmtime获取每个文件的修改时间,并与文件组成元组,方便后续排序 3、默认按照时间戳降序,否则按照按修改时间排序文件列表(从最晚到最早)…