拓扑排序的简单入门题
满足拓扑排序的条件是加入该节点时入度为0
所以每放入一个节点,就把该节点发出的边所到达的顶点的入度减一,然后判断下一个拓扑排序中的点是否满足入度为1,如果满足则继续,不满足肯定不是拓扑排序序列。
注意的地方:
1.把数组作为参数传入函数时,主函数中的数组内容会跟着改变。两个解决策略,一个就是把数组内容复制给另一个新的数组,另一个方法就是不使用函数,直接在主函数中写。
2.把要输出的编号先记录下来,最后一起数组,方便控制空格;也可以用一个变量来判断是否是第一次输入,然后做到边计算边输出。
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=1e3+5;
int n,m;
vector<int> edge[maxn];
bool toporder(vector<int> tmp,int *dg){
for(int i=0;i<tmp.size();i++){
if(dg[tmp[i]]!=0) return false;
for(int j = 0;j < edge[tmp[i]].size(); j++){
dg[edge[tmp[i]][j]]--;
}
}
return true;
}
int main(){
scanf("%d%d",&n,&m);
int deg[maxn],newd[maxn]; //入度
int u, v;
memset(deg,0,sizeof(deg));
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
edge[u].push_back(v);
deg[v]++;
}
int x,k;
scanf("%d",&k);
vector<int> cur,ans;
for(int i=0;i<k; i++){
cur.clear();
for(int i=1;i<=n;i++){
newd[i]=deg[i];
}
for(int j=0;j<n;j++){
scanf("%d",&x);
cur.push_back(x);
}
if(toporder(cur,newd)==false){
ans.push_back(i);
}
}
for(int i=0;i<ans.size();i++){
printf(i==0?"%d":" %d",ans[i]);
}
return 0;
}