简单的拓扑排序
[OI WiKi]什么是拓扑排序?
简单来说,拓扑排序要解决的问题是给一个有向无环图的所有节点排序。
使用一个队列维护入度为零的节点,取出队列中的节点,存入答案,并把该节点的后续节点入度减一,得到新的有向图。
例题一 : 标准拓扑
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>>g(numCourses);
vector<int>indgree(numCourses,0);
for(auto&i:prerequisites){
g[i[1]].push_back(i[0]);
indgree[i[0]]++;
}
queue<int>q;
for(int i=0;i<numCourses;i++){
if(indgree[i]==0){
q.push(i);
}
}
vector<int>ans;
while(!q.empty()){
int i=q.front();
q.pop();
ans.push_back(i);
for(int j:g[i]){
if(--indgree[j]==0){
q.push(j);
}
}
}
return ans.size()==numCourses?ans:vector<int>();
}
};
例题二 : 拓扑+贪心
class Solution {
public:
int scheduleCourse(vector<vector<int>>& courses) {
//按ddl排序
sort(courses.begin(),courses.end(),[](const auto&a1,const auto&a2){
return a1[1]<a2[1];
});
priority_queue<int>q;
int total=0;
for(const auto& cour:courses){
int ti=cour[0],ddl=cour[1];
if(total+ti<=ddl){
//可以加入,直接加
total+=ti;
q.push(ti);
}
else if(!q.empty()&&q.top()>ti){
//有安排的情况下,最后安排的事情耗时大于当前事件
total-=q.top()-ti;
q.pop();
q.push(ti);
}
}
return q.size();
}
};
例题三 : 拓扑 + 搜索
class Solution {
public:
vector<bool> checkIfPrerequisite(int numCourses, vector<vector<int>>& prerequisites, vector<vector<int>>& queries) {
vector<vector<int> >g(numCourses);
vector<int>indgree(numCourses,0);
vector<vector<bool> >isPre(numCourses,vector<bool>(numCourses,false));
for(auto&p:prerequisites){
indgree[p[1]]++;
g[p[0]].push_back(p[1]);
}
queue<int>q;
for(int i=0;i<numCourses;i++){
if(indgree[i]==0){
q.push(i);
}
}
while(!q.empty()){
auto cur=q.front();
q.pop();
//cur的出口
for(auto&out :g[cur]){
isPre[cur][out]=true;
//父节点传递
for(int i=0;i<numCourses;i++){
isPre[i][out]=isPre[i][out] | isPre[i][cur];
}
--indgree[out];
if(indgree[out]==0)q.push(out);
}
}
vector<bool>ans;
for(auto&que:queries){
ans.push_back(isPre[que[0]][que[1]]);
}
return ans;
}
};
本文来自博客园,作者:zhywyt,转载请注明原文链接:https://www.cnblogs.com/zhywyt/p/17704385.html