题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285
拓扑序就是求一个序列 数 a 出现在数 b 前面,最终输出满足条件的序列即可;
过程就是每次选取入度为0的数每次把它计入拓扑序列,并把与该点相连的所有边删除即可;
由于拓扑序不是唯一的本题要求序号小的放前面,所以可以用优先队列;

#include <math.h> #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <queue> #define met(a, b) memset(a, b, sizeof(a)) using namespace std; #define N 510 struct node { int x; bool friend operator < (node a, node b) { return a.x > b.x;///小的先出来; } }; int G[N][N], du[N], n, m, u, v, ans[N]; void topo() { priority_queue<node>Q; node p, q; for(int i=1; i<=n; i++) { if(du[i]==0) p.x=i, Q.push(p); } int k=1; while(Q.size()) { p=Q.top();Q.pop(); ans[k++] = p.x; for(int i=1; i<=n; i++) { if(G[p.x][i]) { du[i]--; if(du[i]==0) q.x=i,Q.push(q); } } } } int main() { while(scanf("%d %d", &n, &m)!=EOF) { met(G,0);met(ans, 0); for(int i=1; i<=m; i++) { scanf("%d %d", &u, &v); if(G[u][v]==0) { G[u][v] = 1; du[v]++; } } topo(); for(int i=1; i<=n; i++) printf("%d%c", ans[i], i==n?' ':' '); } return 0; }