You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
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;
}