拓扑排序+代码
拓扑排序
在一个有向无环图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。
思想:
- 先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点指向的节点的入度减一。
- 一直做改操作,直到所有的节点都被分离出来。
- 如果最后不存在入度为0的节点,那就说明有环,不存在拓扑排序,也就是很多题目的无解的情况。
1->3->4->6->2->5(不唯一)
C++代码:
#include <bits/stdc++.h> #define N 105 using namespace std; int main() { vector <int> m[N]; queue <int> q; //有些拓扑排序要求字典序最小什么的,那就把队列换成优先队列就好了。 //priority_queue<int,vector<int>,greater<int> >q; vector <int> ans; int in[N]; memset(in,0,sizeof(in)); int v,e; cin>>v>>e; for(int i=0;i<e;i++) { int a,b; cin>>a>>b; m[a].push_back(b); } for(int i=1;i<=v;i++) { for(int j=0;j<m[i].size();j++) { in[m[i][j]]++; } } for(int i=1;i<=v;i++) if(in[i]==0) q.push(i); while(!q.empty()) { int p=q.front();q.pop(); ans.push_back(p); for(int i=0;i<m[p].size();i++) { int y=m[p][i]; in[y]--; if(in[y]==0) q.push(y); } } if(ans.size()==v) { for(int i=0;i<ans.size();i++) printf( "%d ",ans[i] ); printf("\n"); } else printf("No Answer!\n"); }