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.
|
|
|
|
#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;
|
|
|
|
|
}
|