首页 > 其他分享 >BFS:边权相同的最短路问题

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

时间:2024-07-11 12:00:02浏览次数:12  
标签:int 边权 BFS vis step vector bx 短路 size

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

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

. - 力扣(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;
    }
};

标签:int,边权,BFS,vis,step,vector,bx,短路,size
From: https://blog.csdn.net/weixin_51142926/article/details/139560862

相关文章

  • 单源最短路
    ABC340DSuperTakahashiBros.问题描述高桥正在玩一个游戏。这个游戏由编号为\(1,2,\ldots,N\)的\(N\)个阶段组成。最初,只有阶段\(1\)是可以玩的。对于每个可以玩的阶段\(i\)(其中\(1\leqi\leqN-1\)),在阶段\(i\)你可以执行以下两个动作之一:花费\(A_i\)秒来通过阶段\(i......
  • 单/全最短路专题 两题
    GregandGraph(Floyd)题意:Greg有一个n个点是一个有边权的有向图这个图两个点都有不一样的边(也就意味着a->b和b->a的权值是不一样的)每次操作都会删除一个点,让这个点和其他和它有关系的点都删除.对于每次删除操作,输出操作以前的最短路径之和思路:这一题的思路......
  • 01bfs
    针对一类特殊图求最短路,如果边权只有01则可以使用双端队列代替堆,将最短路的时间复杂度从\(O(nlogn)\)降为\(O(n)\)。原理:每次所走边边权为0则放队首,边权为1则放队尾。题目1#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#definepiipair<int,int>#......
  • 广度优先搜素 BFS
    广度优先搜索\(\sf\small\color{gray}Breadth\First\Search\)基本思想广度优先搜索,个人认为,和深度优先搜索对比理解要好得多。广度优先搜索,亦称层次遍历,指的是在遍历树上按照从上至下,从左至右的次序遍历整棵树。让我们来看看BFS和DFS的遍历树吧。BFSDFS......
  • 06-6.4.2 最短路径问题
    ......
  • 从零开始学数据结构系列之第四章《 广度优先遍历BFS》
    文章目录广度优先遍历(BFS)概念广度优先遍历算法步骤总代码往期回顾广度优先遍历(BFS)概念​  广度优先遍历(BreadthFirstSearch),又称为广度优先搜索,简称BFS。​  如果说图的深度优先遍历类似树的前序遍历,那么图的广度优先遍历就类似于树的层序遍历了。​ ......
  • C#实现DFS和BFS
    以图示为例:Noderoot=newNode("A",newNode("B",newNode("C"),newNode("D")),newNode("E",newNode("F"),newNode("......
  • 【Python&GIS】基于Geopandas和Shapely计算矢量面最短路径
    ​    在GIS进行空间分析时经常会需要计算最短路径,我也是最近在计算DPC的时候有这方面的需求,刚开始直接是用面的中心点求得距离,但其对不规则或空洞面很不友好。所以今天跟大家分享一下基于Geopandas和Shapely计算矢量面最短路径,这里的最短即点/边的最短!原创作者:RS迷......
  • 12.优化算法之队列+宽搜(BFS)
    BFS——广度优先算法(BreadthFirstSearch)-CSDN博客1.N叉树的层序遍历(广度优先搜索)429.N叉树的层序遍历-力扣(LeetCode)classSolution{publicList<List<Integer>>levelOrder(Noderoot){List<List<Integer>>ret=newLinkedList<>();......
  • 图论最短路径问题与matlab实现
    上一次我们讨论了如何进行图论可视化,这一次我们通过matlab来找出图论中距离最小路径目录一、迪杰斯特拉算法(Dijkstra)二、shortestpath函数用法1.基本语法2.参数设计3.应用实例(1)输入图论信息(2)输入参数进行求解(3)最短路径可视化三、distances函数————求出任意两点的最短路径矩......