本文最后更新于 2024-10-22T11:39:17+00:00
[OI WiKi]什么是拓扑排序?
简单来说,拓扑排序要解决的问题是给一个有向无环图的所有节点排序。
使用一个队列维护入度为零的节点,取出队列中的节点,存入答案,并把该节点的后续节点入度减一,得到新的有向图。
例题一 : 标准拓扑
课程表II
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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>(); } };
|
例题二 : 拓扑+贪心
课程表III
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public: int scheduleCourse(vector<vector<int>>& courses) { 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(); } };
|
例题三 : 拓扑 + 搜索
课程表IV
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 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(); 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; } };
|
简单的拓扑排序
http://hexo.zhywyt.me/posts/11458/