Tree Projection(构造)

题目描述

链接

Given two 1 ∼ n 1\sim n 1n permutations A , B A, B_{} A,B , you should construct an unrooted tree T T_{} T , which satisfies that A A_{} A is a possible topological order of T T_{} T if A 1 A_1 A1 is made the root, and that B B_{} B is a possible dfs order of T T_{} T if B 1 B_1 B1 is made the root.

Here, a permutation P P_{} P of size n n_{} n is a valid topological order of a rooted tree T T_{} T of size n n_{} n iff that for all edges in T T_{} T , the parent nodes are at front of the child nodes in permutation P P_{} P .

输入描述:

The first line contains one integer n   ( 2 ≤ n ≤ 2 × 1 0 5 ) n~(2\le n\le 2\times 10^5) n (2n2×105), denoting the size of permutations.

The second line contains n n_{} n integers A 1 , A 2 , ⋯   , A n A_1, A_2, \cdots, A_n A1,A2,,An , denoting permutation A A_{} A .

The third line contains n n_{} n integers B 1 , B 2 , ⋯   , B n B_1, B_2, \cdots, B_n B1,B2,,Bn , denoting permutation B B_{} B .

输出描述:

If solution exists, print “YES” in one line, and following n − 1 n - 1_{} n1 lines each contains two integers u , v   ( 1 ≤ u , v ≤ n , u ≠ v ) u, v~(1\le u,v \le n, u\neq v) u,v (1u,vn,u=v), denoting one edge in T T_{} T . If multiple solutions exist, print any one of them. If no solution, print “NO” in one line.

输入

5
2 1 4 3 5
4 2 5 1 3

输出

YES
1 2
1 3
2 4
2 5

说明

在这里插入图片描述
思路一

从样例来举例子:

top: 2 1 4 3 5
dfs: 4 2 5 1 3

首先构造一个单枝树 4->2->5->1->3,肯定满足 d f s dfs dfs 序。但是它不满足 t o p top top 序,只能枚举 t o p top top 序的每一个前缀,依次调整 d f s dfs dfs 序,最终使得它同时满足 d f s dfs dfs 序与 t o p top top 序。

设一个 v i s vis vis 标记这是树上的一个分叉,最先标记 t o p [ 1 ] top[1] top[1] ,也就是 2 2 2 是树上的一个分叉( t o p top top 序的根节点)。然后,从 t o p [ 2 ] top[2] top[2] t o p [ n ] top[n] top[n] ,每一个点,都与一个被标记为分叉,并且 d f s dfs dfs 序在当前点的前方,最近的一个点相连。若是它前放没有满足要求的点,那么找它 d f s dfs dfs 序后方,标记为分叉的最近的一个点,与它相连。

说的有些绕,代码如下。复杂度 O ( n   l o g   n ) O(n~log~n) O(n log n)

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,a[N],b[N],pos[N];

int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i],pos[b[i]]=i;
	cout<<"YES\n";
	set<int> st;
	st.insert(0),st.insert(n+1);
	st.insert(pos[a[1]]);
	for(int i=2;i<=n;i++){
		auto ps=st.lower_bound(pos[a[i]]); ps--;
		if(*ps==0) ps++;
		cout<<a[i]<<" "<<b[*ps]<<"\n";
		st.insert(pos[a[i]]);
	}
}

STD

标准答案与前面的的方法很类似了:

top: 2 1 4 3 5
dfs: 4 2 5 1 3

首先根据 t o p top top 序构造一个单枝树 2->1->4->3->5,它肯定满足 t o p top top 序。但是它不满足 d f s dfs dfs 序,然后枚举 d f s dfs dfs 序的每一个前缀,依次调整 t o p top top 序,最终使得它同时满足 d f s dfs dfs 序与 t o p top top 序。

top序调整的时候,每一个结点可以与它前方的任意结点连边,而不破坏 top 序。有一种必定有解的策略是:每一个点,与最前方的满足条件的点相连,之后更新最前方满足要求的点。

说的依旧很迷惑。

复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,a[N],b[N],pos[N];

int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],pos[a[i]]=i;
	for(int i=1;i<=n;i++) cin>>b[i];
	cout<<"YES\n";
	int pre=pos[b[1]];
	for(int i=2;i<=n;i++){
		cout<<b[i]<<" "<<a[pre]<<"\n";
		pre=min(pre,pos[b[i]]);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_51864047

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值