HDU 5444
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5444
题意:
给一棵树。从左往右的命名结点。
先给出这棵树的中序遍历序列。
问对给定的结点编号a,怎么从根节点走到a,输出路径。
思路:
简单题。
容易知道本题的数是一个二叉搜索树,即左子树节点值定小于根节点,右子树节点值定大于根节点。中序遍历一下即可。
下面是并查集的写法。
源码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int MAXN = 1000 + 5;
int fa[MAXN];
int data[MAXN], id[MAXN];
int ans[MAXN];
int cnt;
int n;
void build_tree(int s, int t)
{
// printf("s = %d, t = %d\n", s, t);
if(s == t){
return;
}
else{
if(data[s + 1] > data[s]){
fa[s + 1] = s;
build_tree(s + 1, t);
}
else{
fa[s + 1] = s;
int mark = -1;
for(int i = s + 2 ; i <= t ; i++){
if(data[i] > data[s]){
mark = i;
break;
}
}
if(mark == -1){
build_tree(s + 1, t);
}
else{
build_tree(s + 1, mark - 1);
fa[mark] = s;
build_tree(mark, t);
}
}
}
}
int main()
{
// freopen("1008.in", "r", stdin);
int t;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i = 0 ; i < n ; i++)
scanf("%d", &data[i]), id[data[i]] = i;
for(int i = 0 ; i < n ; i++)
fa[i] = i;
build_tree(0, n - 1);
int q, lv;
scanf("%d", &q);
while(q--){
scanf("%d", &lv);
lv = id[lv];
cnt = 0;
while(fa[lv] != lv){
int f = fa[lv];
// printf("f = %d, lv = %d\n", f, lv);
if(data[f] > data[lv])
ans[cnt++] = 0;
else
ans[cnt++] = 1;
lv = fa[lv];
}
for(int i = cnt - 1 ; i >= 0 ; i--)
printf("%c", ans[i] == 0 ? 'E' : 'W');
printf("\n");
}
}
return 0;
}