在复习了一下拓扑排序后,我选择做这道题练一下。
题目大意:根据题意可知,该题是一道拓扑排序的题(适合新手练习)。附链接http://acm.hdu.edu.cn/showproblem.php?pid=1285。
大体思路:开辟一个二维数组box[505][505]存图,再开一个一维数组topu[505]存各个结点的入度数,这里需要注意的一点是测试数据可能提供重复的数据(WA了一次,找了很久才知道),所以需要先判断再对入度进行加1。然后是循环n次,因为需要输出n个结点。接着是一个从1到n的内循环,确保按照从小到大的顺序得到入度为0的结点,当某个节点入度为0时,再进行一次循环,对该结点可能到达的结点的入度减一。
以下是ac的代码:
#include<iostream>
#include<queue>
using namespace std;
int main(){
int n,m;
while(cin>>n>>m){
int topu[505]={0};
int box[505][505]={0};
int vis[505]={0};
int a,b;
for(int i=0;i<m;i++){
cin>>a>>b;
if(box[a][b]==0){ //输入数据可能有相同的!!!!!!
box[a][b]=1;
topu[b]++;
}
}
queue<int> q;
int cnt=0; //记录最外层循环次数
//循环n次
while(cnt<n){
for(int i=1;i<=n;i++){
if(topu[i]==0&&vis[i]==0){ //判断,排除重复结点
q.push(i);
vis[i]=1;
cnt++;
for(int j=1;j<=n;j++){
if(box[i][j])
topu[j]--;
}
break; //记得break,其实没有也是可以的
}
}
}
int first=1;
while(!q.empty()){
if(first){
first=0;
cout<<q.front();
}
else
cout<<' '<<q.front();
q.pop();
}
cout<<endl;
}
return 0;
}