1. 程式人生 > >演算法題——Course Schedule(C++)有向圖求解BFS

演算法題——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;
    }
};