#include using namespace std; int n, m; /* 测试用例: 4 3 1 2 1 3 1 4 样例输出: 0 1 2 3 */ const int N = 110; struct Node { int l, r, f; } tr[N]; int root[N], rs; bool a[N][N]; int main() { //文件输入 freopen("DuoChaShuToErChaShu.in", "r", stdin); scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) { // m条边 int x, y; scanf("%d %d", &x, &y); a[x][y] = true; // x->y有一条边,先保存起来 } for (int i = 1; i <= n; i++) //双层循环,枚举每个点到点的关系 for (int j = 1; j <= n; j++) if (a[i][j]) { //如果i->j有一条边 if (tr[i].l == 0) { // i没有左儿子 tr[i].l = j; // j就是i的左儿子 tr[j].f = i; // i是j的父亲 } else { int t = tr[i].l; //找到i的左儿子 while (tr[t].r) t = tr[t].r; //一路向下找i的右儿子,右儿子,右儿子... tr[t].r = j; // j做为最终的右儿子 tr[j].f = t; // j的父亲是最终的右儿子 } } //处理森林 for (int i = 1; i <= n; i++) if (!tr[i].f) root[++rs] = i; //将每个子树的根加入到root数组 for (int i = rs; i > 1; i--) { //保留一个根,其它的根合并到前一个根中,从右向左当做右儿子加入 tr[root[i - 1]].r = root[i]; tr[root[i]].f = root[i - 1]; } //输出每个点的父节点号 for (int i = 1; i <= n; i++) printf("%d\n", tr[i].f); return 0; }