1.概念
对于AOV网,我们只需要知道一个AOV网一定是一个有向无环图(Directed Acyclic Graph,DAG)。
拓扑排序,是一个只适合AOV网的算法。
2.拓扑排序
拓扑排序的目标是将所有节点排序,使得排在前面的节点不能依赖于排在后面的节点。因此只有有向无环图可以进行拓扑排序,因为环中的每一个点都有依赖,无法排序。
具体流程
1.首先选择一个入度为0的点
2.删除此顶点以及与此顶点相关联的边
3.重复,知道选不出点了
4.如果ans的个数不等于n,则说明图有环
代码
#include <bits/stdc++.h>
using namespace std;
int n,m,r[205],ans[205],cnt;
bool a[205][205];
int main() {
scanf("%d %d",&n,&m);
for(int i=1,u,v;i<=m;i++) {
scanf("%d %d",&u,&v);
a[u][v]=1,r[v]++;
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(r[j]==0) {
ans[++cnt]=j,r[j]--;
break;
}
}
for(int j=1;j<=n;j++)
if(a[ans[cnt]][j]) r[j]--;
}
if(cnt!=n)
printf("no solution");
else {
for(int i=1;i<=cnt;i++)
printf("%d ",ans[i]);
}
return 0;
}
我们改为邻接表存储和队列存点。
#include <bits/stdc++.h>
#include <vector>
#include <queue>
using namespace std;
int n,m,r[205];
vector<int> a[205],ans;
struct node {
int z;
bool operator <(const node y) const {
return z>y.z; }
node(int Z) {
z=Z; }
};
priority_queue<node> q;
int main() {
scanf("%d %d",&n,&m);
for(int i=1,u,v;i<=m;i++) {
scanf("%d %d",&u,&v);
a[u].push_back(v),r[v]++;
}
for(int i=1;i<=n;i++)
if(r[i]==0) q.push(node(i));
while(q.size()) {
node p=q.top();
q.pop();
ans.push_back(p.z);
for(int i=0;i<a[p.z].size();i++) {
int y=a[p.z][i];
r[y]--;
if(r[y]==0) q.push(y);
}
}
if(ans.size()==n) {
for(int i=0;i<ans.s