#include <iostream>
#include<queue>
#include<algorithm>
#pragma warning(disable:4996)
//#define father 3
using namespace std;
int k, m, n;
int Q, op; int flag;
int trees[5105][3];
int btree[5105][3];
int* troot; int btroot;
bool cmp(int a,int b) {
return a < b;
}
int re=0;
void test0(int root) {
if (root == -1) {
return ;
}
// << root <<" ";
re = re ^ root;
test0(trees[root][1]);
test0(trees[root][2]);
}
void test1(int root) {
if (root == -1) {
return;
}
// << root <<" ";
re = re ^ root;
test1(btree[root][1]);
test1(btree[root][2]);
}
void pre() {
for(int i=0;i<5105;i++)
for (int j = 0; j < 3; j++)
{
trees[i][j] = -1; btree[i][j] = -1;
}
}
void deleteroot(int node) {
int mark = 0;
for (int j = 0; j < m; j++)if (troot[j] == node)mark = j;//troot = troot + 1;
while (mark < m - 1) {
troot[mark] = troot[mark + 1]; mark++;
}troot[mark] = -1;
m--;
}
void testout() {
for (int j = 0; j < m; j++)cout << "根:" << troot[j] << " ";
cout << endl;
for (int j = 0; j < m; j++)
{
test0(troot[j]); cout << endl;
}
}
void clone(int kind) {
if (kind == 1) {//将二叉树数组复制为森林
for (int i = 0; i < 5105; i++)
for (int j = 0; j < 3; j++)
trees[i][j] = btree[i][j];
}
if (kind == 0) {//森林复制为二叉树
for (int i = 0; i < 5105; i++)
for (int j = 0; j < 3; j++)
btree[i][j]= trees[i][j];
}
}
void trans(int flag) {
if (flag == 0) {//森林转二叉树
sort(troot, troot + m, cmp);
int p = troot[0];
for (int i = 1; i < m; i++) {
trees[p][2] = troot[i];
p = troot[i];
}
for (int j = 1; j < m; j++)troot[j] = -1;
m = 1; btroot = troot[0];
//testout();
clone(0);
}
else if (flag == 1) {//二叉树转森林
int p = btroot; int pp =p;
//test1(btroot);
while (p != -1) {
pp = p;
troot[m - 1] = pp;
p = btree[p][2];
btree[pp][2] = -1;
m++;
}
m--;
clone(1);
sort(troot, troot + m, cmp);
//testout();
}
}
void insertbt() {
int ops, fa, node;
cin >> ops >> fa >> node;
if (ops == 0) {
btree[fa][2] = node;
}
if (ops == 1) {
btree[fa][1] = node;
}
}
void meun() {
pre();
cin >> k >> m >> n;
troot = new int[m+1000]; for (int i = 0; i <m+1000; i++)troot[i] = -1;
//cout << trees[11][1] << " vdfv " << trees[11][2] << endl;
if (k == 0) {
flag = 0;
for (int i = 0; i < m; i++)cin >> troot[i];
for (int i = 0; i < n; i++) {
int a, b, * nodes;
cin >> a >> b; nodes = new int[b + 1]; for (int j = 0; j < b; j++)nodes[j] = -1; nodes[b] = -1;
for (int j = 0; j < b; j++)cin >> nodes[j];
sort(nodes, nodes + b, cmp);
if (b != 0) {
trees[a][0] = 0;
trees[a][1] = nodes[0];
int p = 1; int j = nodes[0];
while (nodes[p] != -1) {
trees[j][0]=0;
trees[j][2] = nodes[p];
j = nodes[p]; p++;
}
}
else {
trees[a][0] = 0;
}
}
}
if (k == 1) {
flag = 1;
cin >> btroot;
for (int i = 0; i < n; i++) {
int a, l, r;
cin >> a >> l >> r;
btree[a][1] = l; if (l != -1)btree[l][0] = a;
btree[a][2] = r; if (r != -1)btree[r][0] = a;
}
}
cin >> Q;
for (int i = 0; i < Q; i++) {
cin >> op;
switch (op) {
case 1:
{
int fa, node;
cin >> fa >> node;
if (fa == -1) { trees[node][0] = 0; troot[m] = node; m++; }//插入根节点
else//非根节点
{
trees[node][0] = 0;
int p = trees[fa][1];
if (node <= p || p == -1) {//若小于等于孩子节点||没孩子 则成为该fa的孩子
int ppp = trees[fa][1];
trees[fa][1] = node;
trees[node][2] = ppp;
}
else {
int pp=0;
while (node > p&& p != -1) {
pp = p;
p = trees[p][2];
}
trees[pp][2] = node;
trees[node][2] = p;
}
}
sort(troot, troot + m, cmp);
break;
}
case 2:
{
int fa, node; cin >> fa >> node;
if (fa == -1) {//删掉根节点 则其子节点都会成为新树
deleteroot(node);
if (trees[node][1] != -1) {//删掉的根有孩子
int p = 0;
p = trees[node][1]; int pp;
while (p != -1) {
troot[m] = p;
pp = p;
p = trees[p][2];
trees[pp][2] = -1;
m++;
}
trees[node][0] = -1; trees[node][1] = -1; trees[node][2] = -1;
sort(troot, troot + m, cmp);
}
else {//没孩子
trees[node][0] = -1; trees[node][1] = -1; trees[node][2] = -1;
}
}
else if (fa != -1) {//待删除的点不是根节点 其所有孩子都成为新的树
if (node == trees[fa][1]) { //分情况 1待删除点是其父节点第一个孩子 2其他孩子//我叫白小飞 我遭遇了无法想象的bug,我要活下去,并且干掉更多的bug。awsl
int p = node; trees[fa][1] = trees[p][2];//父节点孩子改变为待删除节点兄弟;
if (trees[p][1]!=-1) {//待删除节点有孩子
int pp = 0; pp = trees[p][1]; int ppp;
while (pp != -1) {
troot[m] = pp;
ppp = pp;
pp = trees[pp][2];
trees[ppp][2] = -1;
m++;
}
sort(troot, troot + m, cmp);
trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
}
else if(trees[p][1]==-1) {//待删除节点无孩子 删除该节点
trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
}
}
else { //分情况 2其他孩子
int p = trees[fa][1]; int pp=0;
while (p!=-1&&p != node) {
pp = p; p = trees[p][2];
}
trees[pp][2] = trees[p][2];//p此时为待删除节点
if (trees[p][1] != -1) {//待删除节点有孩子
int pp = 0;pp= trees[p][1]; int ppp;
while (pp != -1) {
troot[m] = pp;
ppp = pp;
pp = trees[pp][2];
trees[ppp][2] = -1;
m++;
}
sort(troot, troot + m, cmp);
trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
}
else if (trees[p][1] == -1) {//待删除节点无孩子 删除该节点
trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
}
}
}
break;
}
case 3:
{
int a, b; cin >> a >> b;
deleteroot(b);
int p = trees[a][1]; int pp=0;
if (p == -1)trees[a][1] = b;
else {
while (p < b && p != -1) {
pp = p;
p = trees[p][2];
}
if (p == trees[a][1]) {
trees[a][1] = b;
trees[b][2] = p;
}
else {
trees[pp][2] = b;
trees[b][2] = p;
}
}
break;
}
case 4:
{
trans(flag);
flag = (flag + 1) % 2;
//testout();
break;
}
case 5:
{
insertbt();
break;
}
case 6:
{
if (flag == 0) {
sort(troot, troot + m, cmp);
for (int j = 0; j < m; j++)
{
re = 0;
test0(troot[j]);
cout << re << " ";
}
cout << endl;
}
else if (flag == 1) {
re = 0;
test1(btroot);
cout << re << endl;
}
break;
}
}
}
}
int main()
{
//freopen("input13.txt", "r", stdin);
//freopen("output13.txt", "w", stdout);
meun();
//fclose(stdin);
//fclose(stdout);
return 0;
}
森林和二叉树的转换 (孩子兄弟表示法+数组模拟
最新推荐文章于 2022-11-18 18:13:47 发布