字典序拓扑排序
1.用优先队列维护
2.从后往前排序, 每次判断节点的出度, 出度 == 0 , 进入优先队列.
3.用vector数组做邻接表表示整个图
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 30005;
vector<int> per[maxn]; //用邻接表存储图
int out[maxn]; //每个节点的出度
int n, m; //n:节点个数, m:边的个数
int ans[maxn]; //拓扑排序结果
bool topo()
{
int cnt = n;
priority_queue<int> pq;
for(int i = 1; i <= n; ++i)
if(out[i] == 0) pq.push(i); //将所有的出度为零的节点入队
while(!pq.empty())
{
int u = pq.top(); pq.pop();
ans[cnt--] = u; //储存结果
for(int i = 0; i < per[x].size(); ++i)
{
int v = per[u][i];
out[v] --;
if(out[v] == 0) pq.push(v)
}
}
return cnt == 0; //判断是否存在环路
}
普通拓扑排序
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn = 1001;
int per[maxn][maxn]; //邻接矩阵存储
int in[maxn];
stack<int> sta;
vector<int> ans;
int n, m;
bool topo()
{
for(int i = 1; i <= n; ++i)
if(in[i] == 0) sta.push(i); //入度为零的进栈
while(!sta.empty())
{
int u = sta.top();
cout << u <<endl;
sta.pop();
ans.push_back(u);
for(int i = 1; i <= n; ++i)
{
if(per[u][i] == 1)
{
in[i] --; //找到一个边 ,下一个节点入度减一
if(in[i] == 0) sta.push(i);
}
}
}
return ans.size() == n;
}