C - Color the Tree(递归构造)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C - Color the Tree(递归构造)相关的知识,希望对你有一定的参考价值。

LINK

考虑只有一条链的情况,显然操作方案唯一,一路按下来即可

如果有两条链,设链一的状态为 s 1 , s 2 . . . s n s_1,s_2...s_n s1,s2...sn,链二的状态为 t 1 , t 2 . . . . t m t_1,t_2....t_m t1,t2....tm

所有状态都可以达到,形如

( s 1 , t 1 ) − ( s 2 , t 1 ) . . . ( s n , t 1 ) (s_1,t_1)-(s_2,t_1)...(s_n,t_1) (s1,t1)(s2,t1)...(sn,t1)

( s n , t 2 ) − ( s n − 1 , t 2 ) . . . ( s 1 , t 2 ) (s_n,t_2)-(s_{n-1},t_2)...(s_{1},t_2) (sn,t2)(sn1,t2)...(s1,t2)

( s 1 , t 3 ) − ( s 2 , t 3 ) . . . . . (s_1,t_3)-(s_2,t_3)..... (s1,t3)(s2,t3).....

如此往复,所有状态都可以达到

扩展到拥有多个分支,多个子树的复杂树形结构也是如此

先构造前两个子树的情况,然后把前两个子树当作一个子树,再构造和第三个子树的情况

设之前的 k k k个子树对应的答案数组为 a n s ans ans

显然 a n s . s i z e ( ) ans.size() ans.size()个操作对应全部的 a n s . s i z e ( ) + 1 ans.size()+1 ans.size()+1个状态

现在去 d f s dfs dfs k + 1 k+1 k+1个子树得到对应的答案数组 t e m p temp temp

现在我们来合并答案 e d ed ed数组使得所有状态都能取到

先令 e d = a n s ed=ans ed=ans,此时相当于取到

( s 1 , t 1 ) − ( s 2 , t 1 ) . . . ( s n , t 1 ) (s_1,t_1)-(s_2,t_1)...(s_n,t_1) (s1,t1)(s2,t1)...(sn,t1)

此时我们修改 t 1 t_1 t1 t 2 t_2 t2,然后倒序插入 a n s ans ans数组

( s n , t 2 ) − ( s n − 1 , t 2 ) . . . ( s 1 , t 2 ) (s_n,t_2)-(s_{n-1},t_2)...(s_{1},t_2) (sn,t2)(sn1,t2)...(s1,t2)

以此类推

最后需要再 e d ed ed数组的开头插入当前节点(子节点变色前提是父节点变色)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10; 
int n;
vector<int>vec[maxn];
void A_to_B(vector<int>& A,vector<int>& B )
{
	for(auto v:A )	B.push_back( v );
}
vector<int> dfs(int u)
{
	vector<int>ans;
	for( auto v:vec[u] )
	{
		vector<int>temp = ans, now = dfs( v ),invans;
		//temp是前k个子树的答案,合并为一个子树和now来 
		for(int i=ans.size()-1;i>=0;i--)	invans.push_back( ans[i] );
		for(int j=0;j<now.size();j++)
		{
			temp.push_back( now[j] ); 
			if( j&1 )	A_to_B( ans,temp );
			else	A_to_B( invans,temp );
		}
		ans = temp;
	}
	ans.insert(ans.begin(), u);
	return ans;
}
//vector<int> dfs(int u)
//{
//	vector<int>ans;
//	for( auto v:vec[u] )
//	{
//		vector<int>temp = ans, now = dfs( v ),invans;
//		//temp是前k个子树的答案,合并为一个子树和now来 
//		for(int i=ans.size()-1;i>=0;i--)	invans.push_back( ans[i] );
//		for(int j=0;j<now.size();j++)
//		{
//			temp.push_back( now[j] ); 
//			if( j&1 )	temp.insert( temp.end(),ans.begin(),ans.end() );
//			else	temp.insert( temp.end(),ans.rbegin(),ans.rend() );
//		}
//		ans = temp;
//	}
//	ans.insert(ans.begin(), u);
//	return ans;
//}
int main()
{
	cin >> n;
	for(int i=2;i<=n;i++)
	{
		int x; scanf("%d",&x);
		vec[x].push_back( i );
	}
	vector<int>ans = dfs(1);
	ans.erase( ans.begin() );
	cout << ans.size() << endl;
	for( auto v:ans )	printf("%d ",v );
}

以上是关于C - Color the Tree(递归构造)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode | 0106. Construct Binary Tree from Inorder and Postorder Traversal从中序与后序遍历序列构造二叉树Python(示(代

VUE使用vue-tree-color组件实现组织架构图(递归数据,简单明了)

替换法(代入法)求解递归式

hdu 4603 Color the Tree

B. Numbers on Tree(构造详解)

CF1311E Construct the Binary Tree