拓扑排序的简单入门题
满足拓扑排序的条件是加入该节点时入度为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;
}