总时间限制: 1000ms 内存限制: 65535kB
描述
给定一棵二叉树,在二叉树上执行两个操作:
1. 节点交换
把二叉树的两个节点交换。
2. 前驱询问
询问二叉树的一个节点对应的子树最左边的节点。
输入
第一行输出一个整数t(t <= 100),代表测试数据的组数。
对于每组测试数据,第一行输入两个整数n m,n代表二叉树节点的个数,m代表操作的次数。
随后输入n行,每行包含3个整数X Y Z,对应二叉树一个节点的信息。X表示节点的标识,Y表示其左孩子的标识,Z表示其右孩子的标识。
再输入m行,每行对应一次操作。每次操作首先输入一个整数type。
当type=1,节点交换操作,后面跟着输入两个整数x y,表示将标识为x的节点与标识为y的节点交换。输入保证对应的节点不是祖先关系。
当type=2,前驱询问操作,后面跟着输入一个整数x,表示询问标识为x的节点对应子树最左的孩子。
1<=n<=100,节点的标识从0到n-1,根节点始终是0.
m<=100
输出
对于每次询问操作,输出相应的结果。
样例输入
2 5 5 0 1 2 1 -1 -1 2 3 4 3 -1 -1 4 -1 -1 2 0 1 1 2 2 0 1 3 4 2 2 3 2 0 1 2 1 -1 -1 2 -1 -1 1 1 2 2 0
样例输出
1 3 4 2
分析
直接模拟一棵树。按题目要求操作即可。
#include <iostream>
using namespace std;
struct Node {
int f;
int l;
int r;
Node() : f(-1), l(-1), r(-1) {}
};
void swap(Node *tree, int x, int y) {
int xf = tree[x].f;
int yf = tree[y].f;
if (xf != yf) {
tree[y].f = xf;
tree[x].f = yf;
if (tree[xf].l == x) {
tree[xf].l = y;
} else {
tree[xf].r = y;
}
if (tree[yf].l == y) {
tree[yf].l = x;
} else {
tree[yf].r = x;
}
}
else {
if (tree[xf].l == x) {
tree[xf].l = y;
tree[xf].r = x;
} else {
tree[xf].r = y;
tree[xf].l = x;
}
}
}
void query(Node *tree, int x) {
while (tree[x].l != -1) {
x = tree[x].l;
}
cout << x << endl;
}
int handle_case() {
Node tree[100];
int n = 0, m = 0;
cin >> n >> m;
for (int i = 0; i < n; ++i) {
int x = 0, y = 0, z = 0;
cin >> x >> y >> z;
tree[x].l = y;
tree[y].f = x;
tree[x].r = z;
tree[z].f = x;
}
for (int i = 0; i < m; ++i) {
int type = 0, x = 0, y = 0;
cin >> type;
if (type == 1) {
cin >> x >> y;
swap(tree, x, y);
} else if (type == 2) {
cin >> x;
query(tree, x);
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t = 0;
cin >> t;
while (t--) {
handle_case();
}
}