图的拓扑排序 , 判断是否有环
step 1 : 构建元素的入度 (入度:有向图的某个顶点作为终点的次数和。 出度:起点)
step 2 : 找到入度为0的元素, 压入栈中
step 3 : 若栈不为空,将其pop,并找到与其相连接的元素,入度减1,若相连接元素此时入度为0,入栈
例题:课程表
class Solution {
public:
// 图的拓扑排序 , 判断是否有环
// step 1 : 构建元素的入度 (入度:有向图的某个顶点作为终点的次数和。 出度:起点)
// step 2 : 找到入度为0的元素, 压入栈中
// step 3 : 若栈不为空,将其pop,并找到与其相连接的元素,入度减1,若相连接元素此时入度为0,入栈
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int>indegree(numCourses,0);
stack<int> zeroindegree;
unordered_map<int,vector<int>>sameele; // 用来构建邻接表 (用multiset可以快一倍)
for(auto pre : prerequisites) // step 1
{
sameele[pre[0]].push_back(pre[1]);
indegree[pre[1]]++;
}
for(int i = 0 ; i < numCourses ; ++i) // step 2
{
if(indegree[i] == 0)
{
zeroindegree.push(i);
}
}
int count = 0;//用于记录过程中入度为0的元素个数,若count==numCourse, 则该图无环
while(!zeroindegree.empty()) // step 3
{
int temp = zeroindegree.top();
zeroindegree.pop();
++count;
for(auto pr : sameele[temp]) // 只在邻接表里搜索 速度快
{
indegree[pr]--;
if(indegree[pr] == 0)
{
zeroindegree.push(pr);
}
}
}
return count == numCourses;
}
};