算法题——Course Schedule(C++)有向图求解BFS

题目描述:
There are a total of n courses you have to take, labeled from 0 to n – 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

For example:
“ 2, [[1,0],[0,1]] ”
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

读题:
将课程顺序转换为有向图的形式,该有向图中无环则为true。

知识储备:
1. pair
对于pair类,由于它只有两个元素,分别名为first和second,因此直接使用普通的点操作符即可访问其成员。

pair<string, string> a("apple", "banana"); 
string name;
name = a.second;//banana

2.vector
基本操作
(1)头文件#include.
(2)创建vector对象,vector vec;
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素:vec[0] 下标从0开始;
(5)向量大小:vec.size();

3.stack
后入先出(LIFO)
(1)头文件#include.
(2)empty() :堆栈为空则返回真;
(3)pop() :移除栈顶元素
(4)push() :在栈顶增加元素
(5)size() :返回栈中元素数目
(6)top() :返回栈顶元素

解题思路
假设第一个限制条件为[1<–2]
使用BFS遍历图:
1.将输入的限制条件转换为邻接表,

vector< vector> seq(numCourses);
seq[prerequisites[i].second].push_back(prerequisites[i].first);
vector pre = seq[i] 的集合为以结点 i 为前置条件的其他结点;
eg:seq[2]=1

2.计算每个结点的入度(有向图箭头所指的方向,即有前置条件的情况)

indegree[seq[i][j]]++;
eg: indegree[1] = 1;

3.若一个结点的入度为0,说明在它前面没有前置条件,因此一定完成。从入度0的结点开始入栈,如果这个结点是其他结点的前置条件, 将后续结点的入度-1,若后续结点-1后等于0,则又进栈。直到栈为空,说明已经将符合要求的结点都完成了。统计符合要求的结点数量,若与课程数量相同,则说明全部都完成了。

for (int i=0; i<seq[cur].size(); i++) {
                indegree[seq[cur][i]]--;
                if(indegree[seq[cur][i]] == 0)
                    bStack.push(seq[cur][i]);
            }

提交代码:

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        if(numCourses<=1) 
            return true;
        vector<vector<int>> seq(numCourses);
            for (int i=0; i<prerequisites.size(); i++) { seq[prerequisites[i].second].push_back(prerequisites[i].first); 
        }       
        int indegree[numCourses] = {0}; 
        for (int i=0; i<numCourses; i++) {
            for (int j=0; j<seq[i].size(); j++)
                indegree[seq[i][j]]++;
        }

        stack<int> bStack;
        for (int i=0; i<numCourses; i++) {
            if(indegree[i]==0)
                bStack.push(i);
        }
        int node = 0;
        while (!bStack.empty()) {
            int cur = bStack.top();
            node++;
            bStack.pop();
            for (int i=0; i<seq[cur].size(); i++) {
                indegree[seq[cur][i]]--;
                if(indegree[seq[cur][i]] == 0)
                    bStack.push(seq[cur][i]);
            }
        }
        return node == numCourses;
    }
};
点赞