UVA_548
The intuitive idea is to first build the tree and then dfs. Then, after looking at other people's problem-solving reports, we can find that we don't actually need to build a tree, because the process of building a tree is also a process of traversing the tree, in this way, we can simply find out the request.
The core idea of building a tree is that the last value of the subtree's post-sequential traversal must be the root node, so that after finding the root node in the middle-order traversal, then we can divide this subtree into three parts: root node, left subtree, and right subtree. Then we can continue to process the left and right subtree to complete the building process.
#include<stdio.h>
#include<string.h>
#define MAXD 10010
#define INF 0x3f3f3f3f
int N, min, minv, value[MAXD], left[MAXD], right[MAXD], size, inorder[MAXD], postorder[MAXD];
void build(int fa, int flag, int x1, int y1, int x2, int y2)
{
int i, j, k;
++ size;
k = size;
value[k] = postorder[y2];
if(flag)
right[fa] = k;
else
left[fa] = k;
for(i = x1; inorder[i] != postorder[y2]; i ++);
if(i > x1)
build(k, 0, x1, i - 1, x2, x2 + i - 1 - x1);
if(i < y1)
build(k, 1, i + 1, y1, i + y2 - y1, y2 - 1);
}
void dfs(int x, int res)
{
res += value[x];
if(left[x] != -1)
dfs(left[x], res);
if(right[x] != -1)
dfs(right[x], res);
if(left[x] == -1 && right[x] == -1)
{
if(res < min)
{
min = res;
minv = value[x];
}
else if(res == min && value[x] < minv)
minv = value[x];
}
}
void solve()
{
int i, j, k;
memset(left, -1, sizeof(left));
memset(right, -1, sizeof(right));
size = 0;
build(0, 0, 0, N - 1, 0, N - 1);
min = INF;
dfs(1, 0);
printf("%d\n", minv);
}
int main()
{
char ch;
N = 0;
while(scanf("%d%c", &inorder[N ++], &ch) == 2)
{
if(ch == '\n')
{
for(int i = 0; i < N; i ++)
scanf("%d", &postorder[i]);
solve();
N = 0;
}
}
return 0;
}