具体题目见杭电oj1285题。
#include <iostream>
#include <vector>
using namespace std;
//定义了全局变量全部都要初始化。
int inDegree[501];
/*如果只是想实时知道每个点的入度,用一个数组记录就可以,不需要用邻接矩阵存下来。
但是要快速知道每个节点的所有入边是什么,就需要用邻接矩阵存了。*/
//注意,queue和vector都是包含头文件queue、vector的。
vector<int> edge[501]; //用于记录每个结点的出边,便于删除该节点的时候,遍历所有出边的入结点,删除对应的入度。
vector<int> q; //用来记录入度为0的结点,这里推荐用最小堆速度最快,因为相同名次的时候,要找到最小下标的结点出数组。
int main(){
int N, M;
while(cin>>N>>M){
//全局变量初始化。
for(int i=1; i<=N; i++){
inDegree[i] = 0;
edge[i].clear();
}
while(M--){ //把边存储到邻接矩阵和入度记录数组中。
int x, y;
cin>>x>>y;
edge[x].push_back(y);
inDegree[y]++;
}
while(!q.empty()){ //记录入度为0结点的数组的清除,防止运算残留一些结点。
q.clear();
}
for(int i=1; i<=N; i++){ //把入度为0的结点统统收入q中。
if(inDegree[i] == 0){
q.push_back(i);
}
}
bool FirstTime = true;
while(!q.empty()){
int currentNode = 123123;
int index = 0;
for(int i=0; i<q.size(); i++){ //每次取出下标最小的入度为0的结点。
if(q[i] < currentNode){
currentNode = q[i];
index = i;
}
}
q.erase(q.begin()+index, q.begin()+index+1);
if(FirstTime){
cout<<currentNode;
FirstTime = false;
}
else{
cout<<" "<<currentNode;
}
//把该结点指向的结点的入度全部减1。
for(int i=0; i<edge[currentNode].size(); i++){
int y = edge[currentNode][i];
inDegree[y]--;
if(inDegree[y] == 0){ //如果减一后入度为0,该结点入数组q。
q.push_back(y);
}
}
}
cout<<endl;
}
return 0;
}