LeetCode题解之BFS(一)

248 阅读1分钟

宽度优先搜索,常用在最短路径这种题目中

1. 拓扑序列

给定一个包含 n 个节点的有向图 G,我们给出它的节点编号的一种排列,如果满足: 对于图 G 中的任意一条有向边 (u, v),u 在排列中都出现在 v 的前面,则是一种拓扑序列


有相图的拓扑序列:记录每个点的入度和出度,如果是正确的拓扑序列=>就不会存在环=>有相无环图至少存在一个入度为0的点

1.1 207. 课程表

题意也就是说验证这个序列中无环,(a,b)表示b之前必须完成a,那就让a->b
步骤:

  1. 建图并记录所有节点的入度。
  2. 将所有入度为0的节点加入队列。
  3. 取出队首的元素now,将其加入拓扑序列。
  4. 访问所有now的邻接点nxt,将nxt的入度减1,当减到0后,将nxt加入队列。
  5. 重复步骤3、4,直到队列为空。
  6. 如果拓扑序列个数等于节点数,代表该有向图无环,且存在拓扑序。
class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> graph(numCourses);
        vector<int> indegree(numCourses);
        //建图
        for(auto edge : prerequisites)
        {
            graph[edge[0]].push_back(edge[1]);
            indegree[edge[1]] ++;
        }
        queue<int> q;
        int num = 0;
        //加入当前入度为0的点
        for(int i = 0 ; i < numCourses;i ++)
        {
            if(indegree[i] == 0) q.push(i);
        }
        //取出入度为0的点,消去这个点指出去的每条边(也就是指向的点的入度),因为这个边对答案没有影响
        while(!q.empty())
        {
            auto now = q.front();
            q.pop();
            num ++;
            for(int next_pos :graph[now])
            {
                indegree[next_pos] --;
                if(indegree[next_pos] == 0) q.push(next_pos);
            }
        }
        return num == numCourses;

        
    }
};