分析:将先后关系看成边,最后求出字典序最小的拓扑序列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 using namespace std; 6 const int maxn=550; 7 int g[maxn][maxn]; //记录是否存在边 8 int res[maxn]; //记录拓扑序列 9 int edge[maxn]; //记录入度 10 int n,m; 11 void topo(){ 12 for(int i=1;i<=n;i++){ 13 for(int j=1;j<=n;j++){ 14 if(g[i][j]) 15 edge[j]++; 16 } 17 } 18 for(int i=1;i<=n;i++){ 19 int k=1; 20 while(edge[k]!=0) k++; 21 res[i]=k; 22 edge[k]=-1; 23 for(int j=1;j<=n;j++) 24 if(g[k][j]) 25 edge[j]--; 26 } 27 } 28 int main() 29 { 30 while(cin>>n>>m) 31 { 32 memset(g,0,sizeof(g)); 33 memset(res,0,sizeof(res)); 34 memset(edge,0,sizeof(edge)); 35 for(int i=0;i<m;i++){ 36 int x,y; 37 scanf("%d%d",&x,&y); 38 g[x][y]=1; 39 } 40 topo(); 41 for(int i=1;i<n;i++) 42 printf("%d ",res[i]); 43 printf("%d ",res[n]); 44 } 45 }