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