首先说一下拓扑排序:
- 应用条件:只能用在有向无环图中,拓扑排序的生成序列,就是如果A到B之间有一条A->B有向路(不论之间经过了多少节点),那么A一定在B前面。如果图为无向图或者有向有环图,则无法判断具体的那个元素在那个元素之前。就会出现错误
- 实施方法:始终维持一个数组inDegree[]和队列Q,一旦当前度数减少后为零,则立刻加入队列,每次选择队列的中元素出队。由上面的实现方法来看,拓扑排序不唯一。
思路:
无论何时,只要涉及到求图是否为有向无环图的时候,我们都要立刻联想到拓扑排序。
代码如下:
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
vector<int> edge[501];
queue<int> Q;
int main(){
int inDegree[501];
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0)break;
for(int i=0;i<n;i++){
inDegree[i]=0;
edge[i].clear();
}
while(m--){
int a,b;
scanf("%d%d",&a,&b);
inDegree[b]++;
edge[a].pop_back(b);
}
while(Q.empty()==false)Q.pop();
for(int i=0;i<n;i++){
if(inDegree[i]==0)Q.push(i);
}//初始化工作
int cnt=0;
while(Q.empty()==false){
int nowP=Q.front();
Q.pop();
cnt++;
for(int i=0;i<edge[nowP].size();i++){
inDegree[edge[nowP][i]]--;
if(inDegree[edge[nowP][i]]==0){
Q.push(edge[nowP][i]);
}
}
}
//此代码只对应于当前节点进行操作,生成拓扑排序的形式感觉像广搜,但是拓扑排序也可以用深搜的形式实现
//所以拓扑排序不唯一。
if(cnt==n)puts("YES");
else puts("NO");
}
return 0;
}