1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 using namespace std; 5 typedef long long ll; 6 const int N = 150; 7 int in[N],n,r; 8 vector<int>ans; 9 vector<int>edge[N]; 10 priority_queue<int,vector<int>,greater<int> >priq; 11 int main(){ 12 ios::sync_with_stdio(0); 13 cin>>n; 14 for(int i = 1;i <= n;++i){ 15 while(cin>>r){ 16 if(r==0)break; 17 edge[i].push_back(r);in[r]++; 18 } 19 } 20 for(int i = 1;i <= n;++i)if(in[i]==0)priq.push(i); 21 while(!priq.empty()){ 22 23 int p = priq.top();priq.pop(); 24 ans.push_back(p); 25 for(int j = 0;j < edge[p].size();++j){ 26 int y = edge[p][j];in[y]--; 27 if(!in[y])priq.push(y); 28 } 29 } 30 for(int i = 0;i < n;++i){ 31 if(i!=n-1)cout<<ans[i]<<" "; 32 else cout<<ans[i]<<endl; 33 } 34 return 0; 35 }
没什么好说的?自己练习拓排概念用的,目前理解的便是,找到入度为0的点加入队列,如果有字典序或者什么要求则用优先队列自定义排序写,然后删除加入队列的点所连接的边(减去其
指向的点的入度)然后当出现入度为0的点时再次加入队列,直到结束。如果最后队列中的点与所有点数目不一致,就说明有环或者别的,不能使用拓排