BZOJ1149 [CTSC2007]风玲

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;
}

  

posted @ 2017-09-18 17:24  _rqy  阅读(238)  评论(0编辑  收藏  举报