Problem Description
N张地图,每个地图都是二叉树的结构。每个岛屿都有一个资本,这是它的地图的二叉树的根
。
她从这N张地图中选择了k张,并在每张地图的首府城市放置了一个机器人。每个机器人都由一个共同的控制字符串控制。如果控制字符串的当前字符是L(R),则所有机器人移动到其地图上的左(右)子树。所有机器人都遵循相同的控制字符串,并在各自的地图上移动。
对于选择k张,然你求最长的长度。假设n = 2, 让你求k = 1的时候的最长长度,k = 2的时候的最长长度。
思路:
就是把所有树合成一棵树,重叠的结点,记录重叠次数,求出各个重叠次数最深的点,就是字符串的长度。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;//被这里坑惨了,题目没看出数据范围那么大,看了别人AC的数据范围都开那么大,一开就A了。
struct node
{
int l, r;
int cnt;
inline void init()//初始化结点
{
l = r = -1;
cnt = 0;
}
};
node tree1[N], tree2[N];//合成后的树(主树),其他的树(次树)
int ans[N], top;
void Merge(int o, int root, int deep)//o是主树的根,root是次树的根
{
tree1[o].cnt++;//重叠次数++
ans[tree1[o].cnt] = max(ans[tree1[o].cnt], deep);//对应重叠次数,不断更新最大的深度
if(tree2[root].r != -1)
{
if(tree1[o].r == -1)
{
tree1[o].r = ++top;
tree1[tree1[o].r].init();
}
Merge(tree1[o].r, tree2[root].r, deep+1);
}
if(tree2[root].l != -1)
{
if(tree1[o].l == -1)
{
tree1[o].l = ++top;
tree1[tree1[o].l].init();
}
Merge(tree1[o].l, tree2[root].l, deep+1);
}
}
int main()
{
int T, n, m, u, v;
char c[5];
scanf("%d", &T);
while(T--)
{
memset(ans, 0, sizeof(ans));
top = 1;
scanf("%d", &n);
for(int i = 0; i <= n; i++) tree1[i].init();//初始化 主树
for(int j = 1; j <= n; j++)
{
scanf("%d", &m);
for(int i = 0; i <= m; i++) tree2[i].init();//初始化 次树
for(int i = 1; i < m; i++)
{
// printf("~\n");
scanf("%d %s %d", &u, c, &v);
if(c[0] == 'L') tree2[u].l = v;
else tree2[u].r = v;
}
//printf("!\n");
Merge(1, 1, 0);//合成
}
for(int i = 1; i <= n; i++)//输出
{
printf("%d", ans[i]);
if(i == n) printf("\n");
else printf(" ");
}
}
return 0;
}