BZOJ1149 [CTSC2007]风玲

本文介绍了一种算法,用于计算使树形结构中所有叶子节点深度一致所需的最小交换次数。通过递归计算每个节点的最深和最近叶子节点深度来解决此问题,并提供了一段C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Input

Output

输出仅包含一个整数。表示最少需要多少次交换能使风铃满足Ike的条件。如果不可能满足,输出-1。

Sample Input

6
2 3
-1 4
5 6
-1 -1
-1 -1
-1 -1

Sample Output

2

题解

首先,算出每个结点的maxdep和mindep,即这个子树里叶结点的最大、最小深度。

如果maxdep[1]-mindep[1]>1,无解。

看某个结点,如果它的叶结点深度统一,直接忽略;如果它的两个子结点的子树里深度都不是统一的,无解;否则,如果maxdep[l]<=mindep[r],就要交换。反之则不交换。

代码:

#include <algorithm>
#include <cstdio>
const int N = 100050;
int s[N][2], mindep[N], maxdep[N];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", &s[i][0], &s[i][1]);
    s[i][0] = std::max(s[i][0], 0);
    s[i][1] = std::max(s[i][1], 0);
  }
  for (int i = n; i; --i) {
    int l = s[i][0], r = s[i][1];
    mindep[i] = std::min(mindep[l], mindep[r]) + 1;
    maxdep[i] = std::max(maxdep[l], maxdep[r]) + 1;
  }
  if (maxdep[1] - mindep[1] > 1) return puts("-1") & 0;
  int ans = 0;
  for (int o = n; o; --o) {
    if (mindep[o] == maxdep[o]) continue;
    int l = s[o][0], r = s[o][1];
    if (maxdep[l] <= mindep[r])
      ++ans;
    if (mindep[r] != maxdep[r] && mindep[l] != maxdep[l])
      return puts("-1") & 0;
  }
  return printf("%d\n", ans) & 0;
}

  

转载于:https://www.cnblogs.com/y-clever/p/7544149.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值