有向无环图,就是不存在回路的有向图。我们如何判断有向图是否有回路?一般来说,如果该图存在拓扑序列并且能输出所有结点,那么可以证明该图无回路,否则该图有回路
该版本C++的实现采用栈来实现,将入度为0的结点不断入栈,每次弹出栈顶元素,直到栈内为空。弹出一个元素后,将它指向的其他节点的入度减1,不断重复这一过程。
#include <iostream>
#include <stack>
#include <cstring>
#include <set>
#include <vector>
using namespace std;
const int MAXN = 50;
stack<int>s;
set<int>se;
vector<int>vec;
set<int>::iterator it;
vector<int>::iterator it_vec;
int main(){
int EdgeNum; //表示边的个数
cin>>EdgeNum;
int Matrix[MAXN][MAXN]; //用邻接矩阵来存储,0表示不可达,1表示可达
int Ind[MAXN]; //入度数组,表示各点的入度
memset(Ind,0,sizeof(Ind));
memset(Matrix,0,sizeof(Matrix)); //初始化矩阵
for(int i=0;i<EdgeNum;i++){
int a,b;
cin>>a>>b;
Matrix[a][b] = 1;
Ind[b]++;
se.insert(a);
se.insert(b);
}
int length = se.size(); //表示set容器中元素的个数
for(it=se.begin();it!=se.end();it++){
if(Ind[*it] == 0)
s.push(*it); //将入度为0的结点入栈
}
int count = 0; //记录输出的结点数目
while(!s.empty()){
int v = s.top(); //取出栈内的首个元素
s.pop();
vec.push_back(v); //把要输出的结点放到容器中
count++;
for(it=se.begin();it!=se.end();it++){ //找到与v相连的后继结点
if(*it != v && Matrix[v][*it]){
Ind[*it]--;
if(Ind[*it] == 0)
s.push(*it); //若在该过程中又发现入度为0的结点,将该结点入栈
}
}
}
if(count < length)
cout<<"不存在拓扑序列!"<<endl;
else{
for(it_vec = vec.begin();it_vec!=vec.end();it_vec++){
cout<<*it_vec<<" ";
}
cout<<endl;
}
return 0;
}