双向链表练习题(2019牛客国庆集训派对day1)(二叉树)

双向链表练习题(2019牛客国庆集训派对day1)(二叉树)

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld

judge:双向链表练习题

题目描述

Bobo 有 n 个列表 L 1 , L 2 , , L n L_1, L_2, \dots, L_n .
初始时, L i L_i 仅包含元素 i i , 即 L i = [ i ] L_i = [i] 他依次执行了 m m 次操作。第 i i 次操作由两个整数 a i , b i a_i, b_i 指定, 每次操作分为两步:

  1. L a i r e v e r s e ( L a i + L b i ) L_{a_i} \leftarrow \mathrm{reverse}(L_{a_i} + L_{b_i}) , 其中 \leftarrow 表示赋值, + + 表示列表的连接, r e v e r s e \mathrm{reverse} 表示列表的反转。例如, r e v e r s e ( [ 1 , 2 ] + [ 3 , 4 , 5 ] ) = [ 5 , 4 , 3 , 2 , 1 ] \mathrm{reverse}([1, 2] + [3, 4, 5]) = [5, 4, 3, 2, 1] .
  2. L b i [ ] L_{b_i} \leftarrow [] . 其中 [ ] [] 表示空的列表。
    输出 m 次操作后, L 1 L_1 的元素。

输入描述:

输入文件包含多组数据,请处理到文件结束。
每组数据的第一行包含两个整数 n n m m .
接下来 m m 行,其中第 i i 行包含 2 2 个整数 a i , b i a_i, b_i .

  • 1 n , m 1 0 5 1 \leq n, m \leq 10^5

  • 1 a i , b i n , a i b i 1 \leq a_i, b_i \leq n, a_i \neq b_i

  • n n 的总和, m m 的总和都不超过 5 × 1 0 5 5 \times 10^5 .

输出描述:

对于每组数据,先输出 L 1 L_1 的长度 L 1 |L_1| ,再输出 L 1 |L_1| 个整数,表示 L 1 L_1 的元素。

示例1

输入

2 1
1 2
2 1
2 1
3 3
3 2
3 2
1 3

输出

2 2 1
0
3 2 3 1

题解

根据点与点的相对关系建立二叉树,最后从根节点遍历,通过判断奇偶来判断左右孩子的输出顺序。

例如输入

5 3

2 3
2 4
5 2

则数据变化应该为

  1. c n t = 1 cnt=1
    ( L [ 2 ] , L [ 3 ] ) (L[2],L[3])
    l s o n [ 1 ] = N + 3 lson[1]=N+3
    r s o n [ 1 ] = N + 2 rson[1]=N+2
    L [ 2 ] = c n t = 1 L[2]=cnt=1
    L [ 3 ] = 0 L[3]=0
  2. c n t = 2 cnt=2
    ( L [ 2 ] , L [ 4 ] ) (L[2],L[4])
    l s o n [ 2 ] = N + 4 lson[2]=N+4
    r s o n [ 2 ] = L [ 2 ] = 1 rson[2]=L[2]=1
    L [ 2 ] = c n t = 2 L[2]=cnt=2
  3. c n t = 3 cnt=3
    ( L [ 5 ] , L [ 2 ] ) l s o n [ 3 ] = L [ 2 ] = 2 r s o n [ 3 ] = N + 5 L [ 5 ] = c n t = 3 L [ 2 ] = 0 (L[5],L[2])\\lson[3]=L[2]=2\\rson[3]=N+5\\L[5]=cnt=3\\L[2]=0

图解应该是这样
1.
在这里插入图片描述
2.
在这里插入图片描述
3.
在这里插入图片描述

dfs的序应该为

  1. u = L [ 2 ] u=L[2]
    f = 0 a [ 1 ] = N + 4 f=0\\a[1]=N+4
  2. u = 1 u=1
    f = 1 a [ 2 ] = N + 2 a [ 3 ] = N + 3 f=1\\a[2]=N+2\\a[3]=N+3

而如果搜索以 L [ 2 ] L[2] 为根节点的序列,那就从这里开始搜索:
在这里插入图片描述
并且通过判断奇偶可以判断左右孩子的输出顺序

答案应该是4 2 3

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int lson[N], rson[N];
int cnt = 0;
int L[N];
int a[N], tot = 0;
int n, m;
void dfs(int u, int f) {
	if (u > N) {
		a[++tot] = u - N;
		return;
	}
	if (u == 0) return;
	if (f) {
		dfs(rson[u], f ^ 1);
		dfs(lson[u], f ^ 1);
	}
	else {
		dfs(lson[u], f ^ 1);
		dfs(rson[u], f ^ 1);
	}
}
int main() {
	// freopen("in","r",stdin);
	while (scanf("%d %d", &n, &m) == 2) {
		cnt = 0;
		for (int i = 1; i <= n; i++) L[i] = N + i;
		for (int i = 1; i <= m; i++) {
			int a, b;
			scanf("%d %d", &a, &b);
			cnt++;
			lson[cnt] = L[b];
			rson[cnt] = L[a];
			L[a] = cnt;
			L[b] = 0;
		}
		tot = 0;
		dfs(L[1], 0);
		printf("%d", tot);
		for (int i = 1; i <= tot; i++) {
			printf(" %d", a[i]);
		}
		puts("");
	}
	return 0;
}
发布了163 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/101874828
今日推荐