关于拓扑排序的基础知识:算法导论第22章:基本的图算法
#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <list>
#include <stack>
using namespace std;
vector<list<int>> adj; //邻接表
stack<int> zero; //当前入度为0的结点
int deg[105]; //deg[i]保存结点i的入度
vector<int> ans; //拓扑序结果
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,a,b,cur;
while(cin>>n>>m && n)
{
//初始化
memset(deg,0,sizeof(deg));
adj.clear();
ans.clear();
adj.assign(n,list<int>());
for(int i=0; i<m; ++i)
{
cin>>a>>b;
adj[a].push_back(b); //构建邻接表
++deg[b]; //计算每个结点的入度
}
for(int i=0; i<n; ++i)
if(deg[i]==0) zero.push(i); //将入度为0的结点入栈
while(!zero.empty()) //删除入度为0的结点的出边,即减去相应结点的入度
{
cur = zero.top();
zero.pop();
for(list<int>::iterator p = adj[cur].begin(); p != adj[cur].end(); ++p)
{
--deg[*p];
if(deg[*p] == 0) zero.push(*p);
}
ans.push_back(cur); //保存拓扑序
}
cout<<(ans.size() == n ? "YES" : "NO")<<"\n"; //若存在环,则ans.size() < n
}
return 0;
}