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]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
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.
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
題目非常明確的提出了先後拓撲順序,所以採用拓撲排序來實現。在實現拓撲排序時,需要注意幾點:結束的條件是沒有包含入度爲0的節點了;其次是出現環的時候,如(1, 0),(0, 1)的時候該及時停止並返回false。小細節注意之後應該就很好實現了。
void GetInOutDegree(vector<pair<int, int>> &edges, vector<int> &Indegree, map<int, set<int>> &outMap,
set<int> &zeroIn)
{
unsigned len = edges.size();
pair<int, int> tmpPair;
for(unsigned i = 0; i < len; ++i)
{
tmpPair = edges[i];
if(outMap[tmpPair.first].count(tmpPair.second))
continue;
++Indegree[tmpPair.second];
zeroIn.erase(tmpPair.second);
outMap[tmpPair.first].insert(tmpPair.second);
}
}
bool TopSort(int n, vector<int> &Indegree, map<int, set<int>> &outMap, set<int> &zeroIn,
set<int> &dealSet)
{
typedef set<int>::iterator siterator;
if(zeroIn.size() == 0)
{
if(dealSet.size() == n) //滿足拓撲排序要求
return true;
else //還有結點沒有處理,帶有環的情況
return false;
}
int tmp = *(zeroIn.begin());
zeroIn.erase(tmp);
dealSet.insert(tmp);
set<int> tmpSet = outMap[tmp];
siterator end = tmpSet.end();
for(siterator ite = tmpSet.begin(); ite != end; ++ite)
{
if(dealSet.count(*ite)) //出現環時
return false;
else
{
--Indegree[*ite];
if(Indegree[*ite] < 1)
zeroIn.insert(*ite);
}
}
return TopSort(n, Indegree, outMap, zeroIn, dealSet);
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
int len = prerequisites.size();
if(len < 1)
return true;
if(numCourses < 2)
return true;
vector<int> Indegree(numCourses + 5, 0);
map<int, set<int>> outMap;
set<int> zeroIn;
for(int i = 0; i < numCourses; ++i)
zeroIn.insert(i);
GetInOutDegree(prerequisites, Indegree, outMap, zeroIn);
if(zeroIn.size() < 1)
return false;
set<int> dealSet;
return TopSort(numCourses, Indegree, outMap, zeroIn, dealSet);
}